避免 Math.ceil(1.1 * 100) == 111 的最佳实践是什么?用户支付金额不对不能入账,排查了半天才发现 JS 这个逆天设计,好像别的语言也有这样的

22 小时 54 分钟前
 drymonfidelia
3134 次点击
所在节点    JavaScript
40 条回复
rrfeng
22 小时 49 分钟前
基础没学好,回去重修。

---
解决方法就是钱永远别用小数。
AoEiuV020JP
22 小时 45 分钟前
第一反应精度丢失问题,转念想怎么会差这么多, 仔细一看,ceil ,你确定这不是设计如此有人贪这差值吗,
Coelacanthus
22 小时 44 分钟前
计算金融不要用二进制浮点数,二进制浮点数的设计就没法精确表示十进制有理数。用十进制浮点数或者定点数,因为金融业务很少用到分以下,用定点数的比较多。十进制浮点数的支持状态也不太好。
TomVista
22 小时 41 分钟前
biginit
icyalala
22 小时 26 分钟前
"1.1" 是十进制,当这个值转为数字的时候是无限循环小数 1.0001100110011001100110011...
舍入后就是 1.0001100110011001100110011001100110011001100110011010, 注意最后一位是向上舍入的。
所以最开始从 "1.1" 这个字符串解析到数字的时候就已经不准确了。

属实是计算机基础不扎实。
pinocc012
22 小时 13 分钟前
内部数据应该用分为单位的整数吧,显示的时候转换
c8c
22 小时 11 分钟前
`npm install decimal.js`
xiangyuecn
21 小时 30 分钟前
既然用了浮点数 ceil ,哪就不得不得不掏出祖传的 0.30000000000000004.com

php -r var_dump(ceil(1.1*100));
//float(111)
chobitssp
21 小时 29 分钟前
bignumber.js
cmdOptionKana
21 小时 19 分钟前
凡是涉及金额,都不能简单计算。

一个金额,一个日期,这两个是很典型新手误区,表面上看起来没什么,实际上都藏着大坑。
haolongsun
21 小时 6 分钟前
金额永远别用浮点数 用 decimal
haolongsun
21 小时 1 分钟前
二进制只能近似存储小数,详细重新学习 IEEE754 ,还有以前面试区分培训和科班第一个就让说 IEEE754 ,不知道的一定是培训出来的,因为培训班不会说什么浮点数底层怎么实现,而是会说金额不让用 double ,科班必定知道,计组第一章就是吧
importmeta
20 小时 54 分钟前
只用数据库计算
fiveStarLaoliang
20 小时 50 分钟前
string 或者整形存储,计算时得注意精度丢失问题
iOCZS
20 小时 36 分钟前
" JS 这个逆天设计",很野的说法
msg7086
20 小时 29 分钟前
与其说语言的逆天设计,不如说只知道给金额用浮点数的程序员比较逆天吧。
IvanLi127
20 小时 20 分钟前
这个不是常见的面试题么,没见过嘛?

改用 Decimal.js 吧。https://www.npmjs.com/package/decimal.js/v/10.4.3

其他语言也有类似的库,推荐直接用这种方案来做计算。
masterclock
19 小时 33 分钟前
https://github.com/kdeldycke/awesome-falsehood
建议任何程序员写代码前都读一遍

涉及金额,只设计人民币,可以考虑 decimal ,最好是专门的类型
est
18 小时 48 分钟前
测了下 1.1 * 100 == 110.00000000000001 向上取整所以是 111 没问题啊。。。

问题在于 LZ 你为啥要向上取整啊。。round 不行么。
drymonfidelia
17 小时 56 分钟前
@est 因为商品价格 100 美元,税 10%,业务需求是向上取整到整数

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1076556

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX