unit TU2.Helper.Currency;

interface

function CurrencyToChineseCapitalCharacter(const AValue: Currency; const ADecimals: Cardinal=): string;
function CurrencyToString(const AValue: Currency; const ADecimals: Cardinal=): string; implementation uses System.SysUtils, System.Math; function CurrencyRound(var U: UInt64; const ADecimals: Cardinal): Integer; inline;
var
W: UInt64;
begin//Bankers-rounding
Result := -ADecimals;
if Result< then
Result :=
else if Result> then
begin
case Result of
:begin //li
DivMod(U, , U, W);
if (W > ) or ((W = ) and Odd(U)) then
Inc(U);
end;
:begin //fen
DivMod(U, , U, W);
if (W > ) or ((W = ) and Odd(U)) then
Inc(U);
end;
:begin //jiao
DivMod(U, , U, W);
if (W > ) or ((W = ) and Odd(U)) then
Inc(U);
end;
:begin //yuan
DivMod(U, , U, W);
if (W > ) or ((W = ) and Odd(U)) then
Inc(U);
end;
end;
end;
end; function CurrencyToChineseCapitalCharacter(const AValue: Currency; const ADecimals: Cardinal=): string;
const//Currency: [-922337203685477.5807, 922337203685477.5807]
CCCNegative = '负';
CCCZheng = '整';
CCCNumbers: array[..] of Char = ('零','壹','贰','叁','肆','伍','陆','柒','捌','玖');
CCCUnits: array[..] of Char = ('毫', '厘', '分', '角', '元','拾','佰','仟','万',
'拾','佰','仟','亿','拾','佰','仟','万','兆','拾');
var
U, W: UInt64;
Digits, Idx, ZeroFlag: Integer;
Negative: Boolean;
Buff: array[..] of Char;
begin
U := PUInt64(@AValue)^;
if U <> then
begin
Negative := (U and $) <> ;
if Negative then
U := not U + ;
Digits := CurrencyRound(U, ADecimals);
if U<> then
begin
//Try skip trailing zero
repeat
DivMod(U, , U, W);
Inc(Digits);
until W<>;
Dec(Digits);
Idx := ;
if Digits>= then
begin
Buff[Idx] := CCCZheng;
Dec(Idx);
if Digits> then
begin
Buff[Idx] := CCCUnits[];
Dec(Idx);
if Digits> then
begin
Buff[Idx] := CCCUnits[];
Dec(Idx);
end else if Digits> then
begin
Buff[Idx] := CCCUnits[];
Dec(Idx);
end else if Digits> then
begin
Buff[Idx] := CCCUnits[];
Dec(Idx);
end;
end;
end;
Buff[Idx] := CCCUnits[Digits];
Dec(Idx);
Buff[Idx] := CCCNumbers[W];
Dec(Idx);
//Do Split
ZeroFlag := ;
while U<> do
begin
Inc(Digits);
DivMod(U, , U, W);
if Digits in [,,,] then
begin
if ZeroFlag> then
begin
Buff[Idx] := CCCNumbers[];
Dec(Idx);
end else if (ZeroFlag<) and (Digits>) then
Inc(Idx);
Buff[Idx] := CCCUnits[Digits];
Dec(Idx);
if W<> then
begin
Buff[Idx] := CCCNumbers[W];
Dec(Idx);
ZeroFlag := ;
end else
ZeroFlag := -;
end else begin
if W<> then
begin
if ZeroFlag> then
begin
Buff[Idx] := CCCNumbers[];
Dec(Idx);
end;
Buff[Idx] := CCCUnits[Digits];
Dec(Idx);
Buff[Idx] := CCCNumbers[W];
Dec(Idx);
ZeroFlag := ;
end else begin
if ZeroFlag= then
ZeroFlag := ;
end;
end;
end; if Negative then
Buff[Idx] := CCCNegative
else Inc(Idx); //Copy Result
Digits := +-idx;
SetLength(Result, Digits);
Move(Buff[idx], PChar(Result)^, Digits * SizeOf(WideChar));
Exit;
end;
end;
Result := CCCNumbers[]+CCCUnits[]+CCCZheng;
end; function CurrencyToString(const AValue: Currency; const ADecimals: Cardinal=): string;
const
NegativeChar = '-';
DecimalDotChar = '.';
var
U: UInt64;
Digits: Integer;
Negative: Boolean;
begin
U := PUInt64(@AValue)^;
Negative := (U and $) <> ;
if Negative then
U := not U + ;
Digits := CurrencyRound(U, ADecimals);
Result := UIntToStr(U);
if Digits< then
Result := Result.Insert(Result.Length+Digits-, DecimalDotChar);
if Negative then
Result := NegativeChar + Result;
end; 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. delphi中Treeview的使用介绍

    今天重点学习了TreeView的使用方法,基本的已经写了,现在主要想说的是如何显示数据库的资料,今天只是做了个较简单的例子,一个父节点下显示数据库中某个field的值.代码如下: procedure ...

  2. Maven打包将依赖的jar一同打进去

    在pom.xml文件中添加: <build> <plugins> <plugin> <artifactId>maven-assembly-plugin& ...

  3. iOS- 推送消息

    1 ios 如何判断是点击推送信息进入还是点击app图标进入程序? 设备接到apns发来的通知,应用处理通知有以下几种情况: 1. 应用还没有加载 这时如果点击通知的显示按钮,会调用didFinish ...

  4. FFMPEG 常用命令行

    目录 1. 分离音视频 2. 解复用 3. 视频转码 4. 视频封装 5. 视频剪切 6. 视频录制 7.叠加水印 8.将MP3转换为PCM数据 9. 推送RTP流.接收RTP流并存为ts文件 10. ...

  5. skywalking 的安装部署及其远程应用

    环境配置 centos 7.6 jdk 1.8 elasticsearch5.6.8 skyWalking3.2.6 1.安装elasticsearch wget https://artifacts. ...

  6. Burp_Suite_Pro_v1.7.*激活

    先下载工具: 链接:https://pan.baidu.com/s/1ZLvg8eqkgWI94FtrhkcTxg 提取码:9z1j 工具运行需要Java环境.解压完后双击keygen   填一下Li ...

  7. 冲刺Noip2017模拟赛5 解题报告——五十岚芒果酱

    1. 公约数(gcd) [问题描述] 给定一个正整数,在[,n]的范围内,求出有多少个无序数对(a,b)满足 gcd(a,b)=a xor b. [输入格式] 输入共一行,一个正整数n. [输出格式] ...

  8. 数据结构——关于任一二叉树n0=n2+1的证明

    对于任一二叉树,若度为2的结点有n2个,则叶子结点数必为n2+1 证明: 假设该二叉树总共有n个结点(n=n0+n1+n2),则该二叉树总共会有n-1条边,度为2的结点会延伸出两条边, 同理,度为1的 ...

  9. input输入框内容变化实时监听

    js实现的文本框内容发生改变立马触发事件简单介绍:本章节介绍一下如何在文本框的内容发生变化的时候,立马触发一个事件执行响应的操作,而不是像是keydown或者keyup事件一样,只能够检测通过键盘输入 ...

  10. EXCEL 查找某个字符在字符串中最后一次出现的位置

    在EXCEL文档里想从很长的文件路径中取得文件名,[数据]→[分列]是个不错的选择,但用函数会显得更高大上一些. 首先,需要获取最后一个"\"所在的位置. 方法1: FIND(&q ...