ToB企服应用市场:ToB评测及商务社交产业平台
标题:
争论不休的一个话题:金额到底是用Long还是BigDecimal?
[打印本页]
作者:
罪恶克星
时间:
2024-5-17 16:37
标题:
争论不休的一个话题:金额到底是用Long还是BigDecimal?
在网上一直流传着一个争论不休的话题:金额到底是用Long还是用BigDecimal?这个话题一出在哪都会引起异常无比激烈的讨论。。。。
好比说这个观点:算钱用BigDecimal是常识
有支持用Long的,将金额的单位设计为分,然后乘以100,利用Long进行存储以及盘算,这样不用担心小数点问题。
而且一些银行系统就会选择用Long
另有,最最最牛逼的万能大法:用String
成年人不做选择题,Long跟BigDecimal都用。。。
另有一种就是封装一个金额的基类,对金额进行统一处理。
排除float和double
当然,对于金额,首先我们要排除的就是float和double。它们不适合用于精确的金融盘算,由于float和double是基于IEEE 754标准的浮点数表现,它们无法精确地表现所有的十进制小数。这会导致在进行财政盘算时出现舍入误差,这些误差可能会累积并导致不可预测的效果。
关于带精度的盘算,我们不推荐利用float以及double,推荐利用BigDecimal,具体原因请参考:
聊一聊_BigDecimal_利用时的陷阱
选择Long
Long范例在Java中用于存储64位整数。它的主要优点是速度快,由于整数运算在CPU层面黑白常高效的。另外,Long范例也占用较少的内存,而且整数范例(BIGINT)在数据库中占用较少的存储空间。
但是Long范例在处理金额时有几个明显的缺点:
精度问题
:Long只能存储整数,无法直接表现小数。利用Long来表现以分为单位的金额(例如,100表现1元),此时就会失去小数的精度。即使利用某种方式来表现小数(例如,乘以100或10000),也会碰到舍入误差的问题。而且这种盘算方式也会增加盘算的复杂度。
浮点数问题
:固然这不是直接利用Long的问题,但如果你尝试将Long与浮点数(如double或float)进行转换以进行盘算(好比汇率盘算等),还是会碰到浮点数精度问题,这可能导致在财政盘算中出现不可继承的误差。
在阿里巴巴的开发手册中建议利用Long。
但是在一些金融系统当中,对小数位要求比力高的,好比精确到小数点后6位,那么我们利用Long进行存储,每次在盘算时都要除以或者乘以1000000,那么盘算的开销就很大了。
而且,如果在需求确认时,我们无法知道金额要求的小数位,那我们利用Long也是不可的,我们并不知道必要乘以或者除以多少个0。
选择BigDecimal
BigDecimal是Java提供的一个类,用于恣意精度的算术运算。它的主要优点是提供了高精度的盘算,这对于金融和钱币盘算来说黑白常重要的。BigDecimal可以表现恣意巨细的正数、负数或零,并可以精确控制舍入行为。而且在数据库中存储时也有对应的范例进行匹配,好比MySQL的DECIMAL范例提供了精确的数值存储,可以匹配BigDecimal的精度。
但是BigDecimal也有一些缺点:
性能
:与Long相比,BigDecimal的性能较差。由于它的运算必要更多的内存和CPU时间。
复杂性
:利用BigDecimal进行运算比利用Long或基本数据范例更复杂。你必要思量舍入模式、精度等因素。
在数据库中必要更多的存储空间来存储小数部分。
而在Mysql的开发手册中,建议金额必要进行小数位盘算时,存储要利用Decimal,否则我们要将金额乘以对应小数位的倍数变成BIGINT进行存储。
总结
基于上述对Long和BigDecimal的优缺点分析,我们可以得出以下结论:
在金额盘算层面,即代码实现中,推荐利用BigDecimal进行所有与金额相干的盘算。BigDecimal提供了高精度的数值运算,能够确保金额盘算的精确性,制止了因浮点数精度问题导致的财政误差。利用BigDecimal可以简化代码逻辑,镌汰因处理精度问题而引入的复杂性。
而在数据库存储方面,我们必要根据具体需求进行权衡。如果业务需求已经明确金额只需精确到分(如某些国家/地区的钱币最小单位为分),而且我们确信不会涉及到必要更高精度的小数盘算,那么可以利用Long范例进行存储,将金额转换为最小钱币单位(如分)进行存储。这样可以节省存储空间并提高查询性能。
但是如果业务需求中金额的小数位数不确定,或者可能涉及多位小数的盘算(如国际钱币生意业务等),那么最好利用DECIMAL或NUMERIC范例进行存储。这些范例提供了精确的数值存储,可以确保数据库中的数据与应用程序中的BigDecimal对象保持一致,制止数据转换过程中可能引入的精度损失。
本文已收录于我的个人博客:
码农Academy的博客,专注分享Java技术干货,包括Java基础、Spring Boot、Spring Cloud、Mysql、Redis、Elasticsearch、中心件、架构设计、面试题、程序员攻略等
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4