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

18 小时 51 分钟前
 drymonfidelia
2810 次点击
所在节点    JavaScript
40 条回复
rrfeng
18 小时 46 分钟前
基础没学好,回去重修。

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

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

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

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

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

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

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

问题在于 LZ 你为啥要向上取整啊。。round 不行么。
drymonfidelia
13 小时 53 分钟前
@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