数字小写转大写

网上很多数字小写转大写的代码,大多数写得都有问题,找了个以前用过的,在2010下改了改,已测(测试代码在下方)

function GetCnNumber(num: Double): string;
const
  _ChineseNumeric: string = '零一二三四五六七八九';
var
  sIntArabic: string;
  PosOfDecimalPoint: integer;
  i: integer;
  iDigit: integer;
  iSection: integer;
  sSectionArabic: string;
  sSection: string;
  bInZero: boolean;
  bMinus: boolean;
  numstr: string;

  (* 将字串反向, 例如: 传入 '1234', 传回 '4321' *)
  function ConvertStr(const sBeConvert: string): string;
  var
    x: integer;
  begin
    Result := '';
    for x := Length(sBeConvert) downto 1 do
      Result := Result + sBeConvert[x];
  end;
begin
  numstr := FloatToStr(num);
  Result := '';
  bInZero := True;
  if numStr[1] = '-' then
  begin
    bMinus := True;
    numStr := Copy(numStr, 2, Length(numstr));
  end
  else
    bMinus := False;
  PosOfDecimalPoint := Pos('.', numStr);  (* 取得小数点的位置 *)

  (* 先处理整数的部分 *)
  if PosOfDecimalPoint = 0 then
    sIntArabic := ConvertStr(numStr)
  else
    sIntArabic := ConvertStr(Copy(numStr, 1, PosOfDecimalPoint - 1));
  (* 从个位数起以每四位数为一小节 *)
  for iSection := 0 to ((Length(sIntArabic) - 1) div 4) do
  begin
    sSectionArabic := Copy(sIntArabic, iSection * 4 + 1, 4);
    sSection := '';
    (* 以下的 i 控制: 个十百千位四个位数 *)
    for i := 1 to Length(sSectionArabic) do
    begin
      iDigit := Ord(sSectionArabic[i]) - 48;
      if iDigit = 0 then
      begin
        (* 1. 避免 '零' 的重覆出现 *)
        (* 2. 个位数的 0 不必转成 '零' *)
        if (not bInZero) and (i <> 1) then
          sSection := '零' + sSection;
        bInZero := True;
      end
      else
      begin
        case i of
          2: sSection := '十' + sSection;
          3: sSection := '百' + sSection;
          4: sSection := '千' + sSection;
        end;
        sSection := Copy(_ChineseNumeric, iDigit + 1, 1) +
          sSection;
        bInZero := False;
      end;
    end;

    (* 加上该小节的位数 *)
    if Length(sSection) = 0 then
    begin
      if (Length(Result) > 0) and (Copy(Result, 1, 1) <> '零') then
        Result := '零' + Result;
    end
    else
    begin
      case iSection of
        0: Result := sSection;
        1: Result := sSection + '万' + Result;
        2: Result := sSection + '亿' + Result;
        3: Result := sSection + '兆' + Result;
      end;
    end;
  end;

  (* 处理小数点右边的部分 *)
  if PosOfDecimalPoint > 0 then
  begin
    Result := Result + '点';
    for i := PosOfDecimalPoint + 1 to Length(numStr) do
    begin
      iDigit := Ord(numStr[i]) - 48;
      Result := Result + Copy(_ChineseNumeric, iDigit + 1, 1);
    end;
  end;

  (* 其他例外状况的处理 *)
  if Length(Result) = 0 then
    Result := '零';
  if Copy(Result, 1, 2) = '一十' then
    Result := Copy(Result, 2, Length(Result));
  if Copy(Result, 1, 1) = '点' then
    Result := '零' + Result;

  (* 是否为负数 *)
  if bMinus then
    Result := '负' + Result;
end;
测试代码:

procedure Tform1.AddMsg( s: string );
begin
  mmoInfo.Lines.Add( s );
end;

procedure btnTestClick(Sender: TObject);
begin
  AddMsg( GetCnNumber( 5 ));
  AddMsg( GetCnNumber( 15 ));
  AddMsg( GetCnNumber( 25 ));
  AddMsg( GetCnNumber( 115 ));
  AddMsg( GetCnNumber( 1234 ));
  AddMsg( GetCnNumber( 12345 ));
  AddMsg( GetCnNumber( 123456 ));
  AddMsg( GetCnNumber( 1234567 ));
  AddMsg( GetCnNumber( 12345678 ));
  AddMsg( GetCnNumber( 12345008 ));
  AddMsg( GetCnNumber( 12300678 ));

  AddMsg( GetCnNumber( 0.15 ));
  AddMsg( GetCnNumber( 15.12 ));
  AddMsg( GetCnNumber( 12345.2 ));

  AddMsg( GetCnNumber( -12 ));
  AddMsg( GetCnNumber( -12345.2 ));
end;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值