争论不休:金额用Long还是BigDecimal?

问题

今天在网上看到一个有意思的问题,金额的数据类型用Long还是BigDecimal?

具体问题大概是这样的:关于金额的数据类型,组长认为使用BigDecimal比较稳妥,总监认为使用Long才不会出问题,然后开发认为Long用起来比较爽。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从这两个数据类型来看,这家公司使用的开发语言应该是Java,不过换成其它开发语言,也有类似的数据类型选择问题,这是一个广泛存在的问题,所以可以和大家好好聊聊。

网友方案

针对这个问题,热情的网友们从各自的经历出发,提供了很多方案。我大概总结了下,居然有十种之多,虽然有的像调侃,但都有一定的道理。相信大家也很好奇,所以这里我先分享下网友们的方案。

Long

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解读:单位到分,没有小数点,也就没有小数精度的问题。而且Long取值范围也足够了。

BigDecimal

img

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解读:大家都这么用,BigDecimal就是为精确计算而生的。用long不专业,适应性不好。

Long和BigDecimal

img

img

解读:成年人不做选择,成年人什么都要。金额、价格这些用Long,汇率、费率这些要求的小数点比较多,那就用BigDecimal。

String

img

img

解读:万物皆可string。只是处理规则需要全部自己写,高手必备的技能。

Protobuf

img

解读:脱离框架讲方案都是耍流氓。Protobuf里边根本就没有BigDecimal,虽然可以用string或者自定义类型来代表Java中的BigDecimal,不过性能可能要差那么一点点。

自定义

img

img

解读:架构师的好苗子。程序不是能跑起来、不出错就行了,要考虑设计能不能自然体现业务需求,好不好理解、扩展和维护。

听领导的

img

img

解读:霍金来了中国也得站起来敬酒。这根本不是技术问题,一切听领导指示,但是也要做好自我保护。

问AI

img

解读:紧跟时代风口。作为有追求的技术人,就应该想着怎么偷懒怎么最快,先进的生产力工具要用起来,大语言模型回答这个问题滴水不漏、手到擒来,不信你试试!

节省型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

img

解读:节俭是美德。就几百块钱的货,又不是航母和火箭,根本用不着Long,用int、short,甚至byte就能满足。

莫名其妙

img

解读:这个特定芯片是说CPU的位宽不一样吗?比如16位、32位CPU加减乘除的结果可能不同。不懂,真不懂,完全不懂这条评论在说什么问题,请有经验的大神帮解答下。

根本问题

俗话说,结局问题先得明确问题。那么这到底是个什么问题呢?归根到底还是小数的精度问题。

有时候是根本除不尽,比如10除以3;有时候是因为小数的表达问题,编程语言中带小数的数据类型一般是float和double,它们内部使用科学计数法,转换二进制的时候有可能出现无限小数位的问题,比如Javascript中的0.1+0.2算出来就不是0.3,因为浮点数无法精确的表达0.1。

所以为了避免此类问题,大家想出来了各种各样的方法。

其实使用Long和BigDecimal的本质都是一样的,都是避免使用浮点数进行表达,只是Long属于隐式设定小数点,BigDecimal属于显示设定小数点。

比如,使用Long表示价格时,系统约定单位是分,那么9999就代表99.99元;而使用BigDecimal表示价格时,则需要明确小数位 new BigDecimal(“99.99”)。

另外不管是Long还是BigDecaimal在进行除法运算时,只要发生除不尽,就存在精度问题。

解决方案

这里我做个总结。

在程序中处理金额时,最佳实践通常是使用类似BigDecimal的数据类型,因为它提供了精确的小数运算能力,这对于财务计算来说非常重要。使用BigDecimal可以避免因浮点数的精度问题导致的计算误差,这些误差在金融应用中可能会导致严重的问题。

BigDecimal可以精确地表示和计算小数,它允许你定义小数点后的精度,并且提供了一系列的舍入模式。这意味着当你需要执行加减乘除时,可以控制舍入行为以符合金融计算的要求。

另一方面,虽然使用Long类型来表示金额(通常以分为单位)也是一种选择,因为它避免了小数的使用,从而也能保证精确性。但是,这种方法在表示和处理小数时就不那么直观,而且在需要进行货币转换或者涉及到小数的计算时,你必须自己管理小数点的位置。

例如,如果使用Long表示金额,你需要记住金额是以分为单位还是以元为单位,而且在报告或用户界面中显示金额时,通常需要将金额转换为以元为单位的格式,这就需要额外的计算步骤。

所以,虽然Long类型也可以用来精确地表示金额,但是为了代码的可读性、易用性和减少手动处理小数点的错误,推荐使用BigDecimal来处理金额。这是一种更安全、更灵活的方法,尤其是在需要精确计算小数时。

其它使用string或者自定义类的方案,当然也可以,只是需要更多的工作来完善数据处理的各种规则,容易出错,也不规范,为什么不使用现成的BigDecimal呢?


以上就是本文的主要内容。

关注萤火架构,提升技术不迷路!

  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值