1. unit TU2.Helper.Currency;
  2.  
  3. interface
  4.  
  5. function CurrencyToChineseCapitalCharacter(const AValue: Currency; const ADecimals: Cardinal=): string;
  6. function CurrencyToString(const AValue: Currency; const ADecimals: Cardinal=): string;
  7.  
  8. implementation
  9.  
  10. uses System.SysUtils, System.Math;
  11.  
  12. function CurrencyRound(var U: UInt64; const ADecimals: Cardinal): Integer; inline;
  13. var
  14. W: UInt64;
  15. begin//Bankers-rounding
  16. Result := -ADecimals;
  17. if Result< then
  18. Result :=
  19. else if Result> then
  20. begin
  21. case Result of
  22. :begin //li
  23. DivMod(U, , U, W);
  24. if (W > ) or ((W = ) and Odd(U)) then
  25. Inc(U);
  26. end;
  27. :begin //fen
  28. DivMod(U, , U, W);
  29. if (W > ) or ((W = ) and Odd(U)) then
  30. Inc(U);
  31. end;
  32. :begin //jiao
  33. DivMod(U, , U, W);
  34. if (W > ) or ((W = ) and Odd(U)) then
  35. Inc(U);
  36. end;
  37. :begin //yuan
  38. DivMod(U, , U, W);
  39. if (W > ) or ((W = ) and Odd(U)) then
  40. Inc(U);
  41. end;
  42. end;
  43. end;
  44. end;
  45.  
  46. function CurrencyToChineseCapitalCharacter(const AValue: Currency; const ADecimals: Cardinal=): string;
  47. const//Currency: [-922337203685477.5807, 922337203685477.5807]
  48. CCCNegative = '负';
  49. CCCZheng = '整';
  50. CCCNumbers: array[..] of Char = ('零','壹','贰','叁','肆','伍','陆','柒','捌','玖');
  51. CCCUnits: array[..] of Char = ('毫', '厘', '分', '角', '元','拾','佰','仟','万',
  52. '拾','佰','仟','亿','拾','佰','仟','万','兆','拾');
  53. var
  54. U, W: UInt64;
  55. Digits, Idx, ZeroFlag: Integer;
  56. Negative: Boolean;
  57. Buff: array[..] of Char;
  58. begin
  59. U := PUInt64(@AValue)^;
  60. if U <> then
  61. begin
  62. Negative := (U and $) <> ;
  63. if Negative then
  64. U := not U + ;
  65. Digits := CurrencyRound(U, ADecimals);
  66. if U<> then
  67. begin
  68. //Try skip trailing zero
  69. repeat
  70. DivMod(U, , U, W);
  71. Inc(Digits);
  72. until W<>;
  73. Dec(Digits);
  74. Idx := ;
  75. if Digits>= then
  76. begin
  77. Buff[Idx] := CCCZheng;
  78. Dec(Idx);
  79. if Digits> then
  80. begin
  81. Buff[Idx] := CCCUnits[];
  82. Dec(Idx);
  83. if Digits> then
  84. begin
  85. Buff[Idx] := CCCUnits[];
  86. Dec(Idx);
  87. end else if Digits> then
  88. begin
  89. Buff[Idx] := CCCUnits[];
  90. Dec(Idx);
  91. end else if Digits> then
  92. begin
  93. Buff[Idx] := CCCUnits[];
  94. Dec(Idx);
  95. end;
  96. end;
  97. end;
  98. Buff[Idx] := CCCUnits[Digits];
  99. Dec(Idx);
  100. Buff[Idx] := CCCNumbers[W];
  101. Dec(Idx);
  102. //Do Split
  103. ZeroFlag := ;
  104. while U<> do
  105. begin
  106. Inc(Digits);
  107. DivMod(U, , U, W);
  108. if Digits in [,,,] then
  109. begin
  110. if ZeroFlag> then
  111. begin
  112. Buff[Idx] := CCCNumbers[];
  113. Dec(Idx);
  114. end else if (ZeroFlag<) and (Digits>) then
  115. Inc(Idx);
  116. Buff[Idx] := CCCUnits[Digits];
  117. Dec(Idx);
  118. if W<> then
  119. begin
  120. Buff[Idx] := CCCNumbers[W];
  121. Dec(Idx);
  122. ZeroFlag := ;
  123. end else
  124. ZeroFlag := -;
  125. end else begin
  126. if W<> then
  127. begin
  128. if ZeroFlag> then
  129. begin
  130. Buff[Idx] := CCCNumbers[];
  131. Dec(Idx);
  132. end;
  133. Buff[Idx] := CCCUnits[Digits];
  134. Dec(Idx);
  135. Buff[Idx] := CCCNumbers[W];
  136. Dec(Idx);
  137. ZeroFlag := ;
  138. end else begin
  139. if ZeroFlag= then
  140. ZeroFlag := ;
  141. end;
  142. end;
  143. end;
  144.  
  145. if Negative then
  146. Buff[Idx] := CCCNegative
  147. else Inc(Idx);
  148.  
  149. //Copy Result
  150. Digits := +-idx;
  151. SetLength(Result, Digits);
  152. Move(Buff[idx], PChar(Result)^, Digits * SizeOf(WideChar));
  153. Exit;
  154. end;
  155. end;
  156. Result := CCCNumbers[]+CCCUnits[]+CCCZheng;
  157. end;
  158.  
  159. function CurrencyToString(const AValue: Currency; const ADecimals: Cardinal=): string;
  160. const
  161. NegativeChar = '-';
  162. DecimalDotChar = '.';
  163. var
  164. U: UInt64;
  165. Digits: Integer;
  166. Negative: Boolean;
  167. begin
  168. U := PUInt64(@AValue)^;
  169. Negative := (U and $) <> ;
  170. if Negative then
  171. U := not U + ;
  172. Digits := CurrencyRound(U, ADecimals);
  173. Result := UIntToStr(U);
  174. if Digits< then
  175. Result := Result.Insert(Result.Length+Digits-, DecimalDotChar);
  176. if Negative then
  177. Result := NegativeChar + Result;
  178. end;
  179.  
  180. end.

在Delphi中,为了实现货币数值运算中的严格精度要求,内部把货币类型数据当作一个放大10000倍的64位整数来处理。这样根据64位整数的范围,可以得出货币类型Currency的范围是 [-922337203685477.5807; 922337203685477.5807]。
货币类型一个最常见的应用场景是金额大写转换,网上都是一些先将货币转字符串后再对字符串处理的代码,而且有些方法在有些情况下不满足金额大写规范,这里给出一个直接转换的方法。

附: 金额大写规范
一、人民币大写金额数字到“元”为止的,在“元”之后,应写“整”(或“正”)字;在“角”之后,可以不写“整”(或“正”)字;大写金额数字有“分”的,“分”后面不写“整”(或“正”)字。
二、阿拉伯数字小写金额数字中有“0”时,人民币大写应按照汉语语言规律。举例如下:
1. 阿拉伯金额数字中间有“0”时,人民币大写要写“零”字。如¥1409.50,应写成人民币陆壹仟肆佰零玖元伍角。
2. 阿拉伯金额数字中间连续有几个“0”时,人民币大写金额中间可以只写一个“零”字。如¥6007.14,应写成人民币陆仟零柒元壹角肆分。
3. 阿拉伯金额数字万位和元位是“0”;或者数字中间连续有几个“0”,万位(或元位)也是“0”,但千位(或角位)不是“0”时;中文大写金额中可以只写一个零字,也可以不写“零”字。如¥1680.32,应写成人民币壹仟陆佰捌拾元零叁角贰分或者写成人民币壹仟陆佰捌拾元叁角贰分。又如¥107000.53,应写成人民币壹拾万柒仟元零伍角叁分或者写成人民币壹拾万零柒仟元伍角叁分。
4. 阿拉伯金额数字角位是“0”,而分位不是“0”时,中文大写金额“元”后面应写“零”字。如¥16409.02,应写成人民币壹万陆仟肆佰零玖元零贰分,又如¥325.04.应写成人民币叁佰贰拾伍元零肆分。
————————————————
版权声明:本文为CSDN博主「tht2009」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tht2009/article/details/73287225

以上为作者原文内容,我对CurrencyToChineseCapitalCharacter函数在Android及Windows10上做了测试,结果正常。Delphi 版本10.3.2.感谢作者的分享!这是一个最有效率的实现方法!

【转】Delphi货币类型转中文大写金额的更多相关文章

  1. c#金额转换成中文大写金额 .Net开发Windows服务

    c#金额转换成中文大写金额   2018-08-24 转别人 c#金额转换成中文大写金额 /// <summary> /// 金额转换成中文大写金额 /// </summary> ...

  2. JavaScript将输入的数字金额转换成对应的中文大写金额

    // 将输入的数字金额转换成对应的中文大写金额 // idNumber输入的数字金额,idCHN输出的中文大写金额 function TransformNumberIntoCHN(idNumber, ...

  3. CRM后期修改实体,新增货币类型字段 需要注意的问题

    货币类型字段新增 需要处理历史数据 否则编辑会报错 提示如果货币字段中存在值,则需要指定币种,请选择币种,然后重试 编辑时货币字段不显示¥符号.新增正常.第一次编辑提示错误保存后再编辑也正常.不是JS ...

  4. js中的数字格式变成货币类型的格式

    <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...

  5. JS实现 阿拉伯数字金额转换为中文大写金额 可以处理负值

    JS实现 阿拉伯数字金额转换为中文大写金额 可以处理负值 //************************* 把数字金额转换成中文大写数字的函数(可处理负值) ****************** ...

  6. c#金额转换成中文大写金额

    2018-08-24 转别人 c#金额转换成中文大写金额 /// <summary> /// 金额转换成中文大写金额 /// </summary> /// <param ...

  7. C#中货币类型和数值类型、字符串类型的转化

    1.定义textbox的数据 private void Form1_Load(object sender, EventArgs e) { this.textBox1.Text = String.For ...

  8. PHP 数字金额转换成中文大写金额的函数 数字转中文

    /** *数字金额转换成中文大写金额的函数 *String Int $num 要转换的小写数字或小写字符串 *return 大写字母 *小数位为两位 **/ function num_to_rmb($ ...

  9. 在C#中将金额转换成中文大写金额

    具体代码如下: /// <summary> /// 金额转换成中文大写金额 /// </summary> /// <param name="LowerMoney ...

随机推荐

  1. opengl读取灰度图生成三维地形

    准备第三方库 glew.freeglut.glm.opencv 准备灰度图片和草地贴图 最终效果 代码包括主程序源文件mainApp.cpp.顶点着色器shader.vs.片元着色器shader.fs ...

  2. WordPress自定义菜单和修改去除多余的css

    这里主要是用于模板制作的,一般前端已经写好了,我们只要将前端的内容套用WordPress后台就可以了. 所以我们在模板制作过程中,需要自定义WordPress菜单. 在functions.php文件中 ...

  3. Laravel核心代码学习

    原文地址:https://github.com/kevinyan815/Learning_Laravel_Kernel

  4. 读rfc HTTP 协议

    这是IETF ( 国际互联网工程任务组(The Internet Engineering Task Force,简称 IETF))制定的协议之一. 互联网工程任务组,成立于1985年底,是全球互联网最 ...

  5. windows10激活出现0xC0000022

    怎么办?不要担心,先找到了C:\Windows\System32\spp\store 文件夹,查看了下它的权限,如没有sppsvc,则手动添加了NT SERVICE\sppsvc 并给完全控制的权限. ...

  6. AndroidMainfest详解

    基于TV settings和SettingsProvider Android启动模式对activity行为的影响 AndroidManifest.xml文件详解 Manifest文件中,applica ...

  7. jquery防止快速点击

    jquery防止快速点击(推荐第三种方式) //全站ajax加载提示 (function ($) { var str = '<div class="ajax-status" ...

  8. [转帖]postgresql查看用户连接以及杀死连接的会话

    postgresql查看用户连接以及杀死连接的会话 2017年10月11日 15:21:18 DB_su 阅读数 8908更多 分类专栏: postgresql   版权声明:本文为博主原创文章,遵循 ...

  9. RMI(远程方法调用)

    Remote Method Invocation  跨虚拟机间调用 使用 RMI 技术可轻松将 服务提供者(Service Provider)与 服务消费者(Service Consumer)进行分离 ...

  10. 第7章:LeetCode--算法:递归问题

    70. Climbing Stairs This problem is a Fibonacci problem.F(n)=F(n-1)+F(n-2);Solving this problem by r ...