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. BTE增强

    转自https://www.cnblogs.com/Garfield/p/5313962.html Enhancement(1)--BTEs 最近一个同事碰到一个FI的增强,要用BTEs实现,我也是第 ...

  2. 如何将Nginx注册为系统服务,开机自启动

    亲测有效! 一般程序员在实际工作中,除了敲代码,很少有机会实际接触操作其它东西,例如服务器环境搭建,项目部署等等,不是领导信任或项目组核心成员,应该是没有机会实际接触的,只能通过网上资料稍微了解一下. ...

  3. Unity Shader基础(1):基础

    一.Shaderlab语法 1.给Shader起名字 Shader "Custom/MyShader" 这个名称会出现在材质选择使用的下拉列表里 2. Properties (属性 ...

  4. Telegram Groups vs Telegram Channels

    Telegram Groups vs Telegram Channels By Iaroslav Kudritskiy  Unlike other messaging apps, using Tele ...

  5. linux基本防护措施,权限分配和提高防护安全

    设置用户失效 1.失效的用户将无法登录 使用chage命令将用户zhangsan的账户设为当前已失效(比如已经过去的某个时间): [root@proxy ~]# useradd zhangsan [r ...

  6. Java学习笔记-包,classpath,import,jar

    这里介绍Java的包,classpath,import和jar 包(package) 对类文件进行分类管理 给类提供多层命名空间 写在程序文件的第一行 类名的全称的是 包名.类名 包也是一种封装形式 ...

  7. IO阻塞模型、IO非阻塞模型、多路复用IO模型

    IO操作主要包括两类: 本地IO 网络IO 本地IO:本地IO是指本地的文件读取等操作,本地IO的优化主要是在操作系统中进行,我们对于本地IO的优化作用十分有限 网络IO:网络IO指的是在进行网络操作 ...

  8. HanLP-朴素贝叶斯分类预测缺陷

    文章整理自 baiziyu 的知乎专栏,感兴趣的朋友可以去关注下这位大神的专栏,很多关于自然语言处理的文章写的很不错.昨天看到他的分享的两篇关于朴素贝叶斯分类预测的文章,整理了一下分享给给大家,文章已 ...

  9. centos 安装go

    [root@golong-learning src]# wget https://dl.google.com/go/go1.12.7.linux-amd64.tar.gz # 下载 [root@gol ...

  10. Hystrix的概念

             Netflix的 Hystrix 是一个帮助解决分布式系统交互时超时处理和容错的类库, 它同样拥有保护系统的能力.       Hystrix的设计原则包括:资源隔离.熔断器.命令模 ...