1
rrfeng 63 天前 via Android 6
基础没学好,回去重修。
--- 解决方法就是钱永远别用小数。 |
2
AoEiuV020JP 63 天前 2
第一反应精度丢失问题,转念想怎么会差这么多, 仔细一看,ceil ,你确定这不是设计如此有人贪这差值吗,
|
3
Coelacanthus 63 天前
计算金融不要用二进制浮点数,二进制浮点数的设计就没法精确表示十进制有理数。用十进制浮点数或者定点数,因为金融业务很少用到分以下,用定点数的比较多。十进制浮点数的支持状态也不太好。
|
4
TomVista 63 天前
biginit
|
5
icyalala 63 天前 2
"1.1" 是十进制,当这个值转为数字的时候是无限循环小数 1.0001100110011001100110011...
舍入后就是 1.0001100110011001100110011001100110011001100110011010, 注意最后一位是向上舍入的。 所以最开始从 "1.1" 这个字符串解析到数字的时候就已经不准确了。 属实是计算机基础不扎实。 |
6
pinocc012 63 天前
内部数据应该用分为单位的整数吧,显示的时候转换
|
7
c8c 63 天前
`npm install decimal.js`
|
8
xiangyuecn 63 天前 1
|
9
chobitssp 63 天前
bignumber.js
|
10
cmdOptionKana 63 天前
凡是涉及金额,都不能简单计算。
一个金额,一个日期,这两个是很典型新手误区,表面上看起来没什么,实际上都藏着大坑。 |
11
haolongsun 63 天前
金额永远别用浮点数 用 decimal
|
12
haolongsun 63 天前
二进制只能近似存储小数,详细重新学习 IEEE754 ,还有以前面试区分培训和科班第一个就让说 IEEE754 ,不知道的一定是培训出来的,因为培训班不会说什么浮点数底层怎么实现,而是会说金额不让用 double ,科班必定知道,计组第一章就是吧
|
13
importmeta 63 天前
只用数据库计算
|
14
fiveStarLaoliang 63 天前
string 或者整形存储,计算时得注意精度丢失问题
|
15
iOCZS 63 天前 2
" JS 这个逆天设计",很野的说法
|
16
msg7086 63 天前 1
与其说语言的逆天设计,不如说只知道给金额用浮点数的程序员比较逆天吧。
|
17
IvanLi127 63 天前
这个不是常见的面试题么,没见过嘛?
改用 Decimal.js 吧。https://www.npmjs.com/package/decimal.js/v/10.4.3 其他语言也有类似的库,推荐直接用这种方案来做计算。 |
18
masterclock 63 天前 3
|
19
est 63 天前
测了下 1.1 * 100 == 110.00000000000001 向上取整所以是 111 没问题啊。。。
问题在于 LZ 你为啥要向上取整啊。。round 不行么。 |
20
drymonfidelia OP @est 因为商品价格 100 美元,税 10%,业务需求是向上取整到整数
|
21
DOLLOR 63 天前
浮点运算你换什么语言都一样。
涉及财务、金融的计算,*不能用浮点数*,要用*定点数*,这应该是程序员的常识、共识。 |
22
ntedshen 63 天前 1
“业务需求是向上取整到整数”?
简单, Math.ceil(Math.round(1.1*10000)/100) 然后下一届码农:md 屎山+1 (狗头 |
23
drymonfidelia OP @ntedshen 我真的改成了这样 (狗头
|
24
mingl0280 63 天前
涉及钱币为什么要用浮点数?
|
26
geelaw 63 天前 via iPhone
@drymonfidelia #20 正确的做法是金额存成 cPrice = 10000 美分,税计算为 ((cPrice * 10000 * bpTaxRate - 1) / 10000 + 1) 美分,其中 bpTaxRate 是税率的基点数(万分之几)。这里假设 cPrice 是非负数(销售),处理退款更麻烦。
|
28
whileFalse 63 天前 via Android
lz 培训班的,鉴定完毕
|
29
lovestudykid 63 天前
计算机就业状况还是太好了
|
30
lithiumii 63 天前 via Android
ceil 是上取整,你就算是不懂浮点数,用四舍五入这个 bug 也会少很多
|
31
lee88688 63 天前
#22 的做法其实是正确的,不算什么屎山。使用二进制浮点数表示十进制浮点数在一定有效位数下可以认为是正确的,这个有效位数在 64 位浮点数下大概是 12 位。
在这些位数下转换成整数,然后将整数和小数部分取出来做处理完全没问题,楼主只需要写一些注释,后续人理解没问题的。 |
32
lee88688 63 天前
多说一句,这种是将浮点数进行最终处理和简单时的做法。因为这些误差在累积计算的时候可能会让偏差越来越大,因此计算的时候还是使用浮点数需要做额外的处理,最好还是使用十进制的库计算或者用 bigint 转化为整数计算。
|
33
ahu 63 天前
如 #8 所说,去看看这个网站:
location.href = 'http://' + (.1 + .2) + '.com'; |
34
Curtion 63 天前
这是 IEEE754 的问题,金额相关不要用浮点数,要么使用 Decimal ,要么浮点数拆开成两个整数分开存储
|
35
mdn 63 天前
采用 IEEE 754 浮点数运算的标准的语言 都会出现这个问题,包括 JavaScript Java Python 等
建议使用数学库进行运算 |
36
lyxxxh2 63 天前 1
你不该说逆天设计,不是找喷吗。
对金额敏感,用数学库,big.js 之类。 |
37
wu67 63 天前
npm install mathjs -S
|
38
EndlessMemory 63 天前
0.1+0.2==0.3 ?
|
39
sastar 63 天前
判断 0.1+0.2==0.3 的正确用法应该是 abs(0.1+0.2-0.3)<0.000001 ,具体在小数点后多少位取决于你对精度的要求
|
40
winglight2016 63 天前 1
有点不理解 lz 这个代码是前端还是后端?如果是后端,从数据库设计开始就肯定用整数保存金额啊,包括银行也是这样。
如果是前端,那根本就不该去做计税这个操作——正确的设计是把用户输入全部发送到后端去计算。 |
41
thtznet 61 天前
拿 JS 这种前端语言计算金额?还拿去对账?逆天考量。
|
42
zhhbstudio 53 天前
@xiangyuecn #8 好东西,收藏了,哈哈哈
|