只需要保证小数点后两位计算正确, 用 float 有问题吗?

2017-07-07 17:31:38 +08:00
 petelin

用浮点数表达十进制中的小数会出现误差, 但是这个误差极小, 基本上计算出来的都是 0.xx00000000xxx 或者 0.xx99999999xxx, 这个时候我们只取小数点后两位应该是很精确地, 我想不到什么时候这样会出问题, 求指教

6439 次点击
所在节点    数学
25 条回复
petelin
2017-07-09 18:37:51 +08:00
@zoudm 为什么这个误差这么大, 我用 python 实验的时候, `sum(0.1 for i in range(100000))` 结果是 10000.000000018848, 我觉得可以接受啊
petelin
2017-07-09 18:38:17 +08:00
确实是存金额, 老大不让用分.........
petelin
2017-07-09 18:41:55 +08:00
@BigBearWatchYou 试了一下是 1000000.0, 这样的话在 java 里肯定不能用了. 现在比较好奇为什么 python 对浮点数处理这么好,
In [29]: Decimal(float(99999.99))
Out[29]: Decimal('99999.990000000005238689482212066650390625')
误差都很小的, 包括上面一位同学给出的 C 代码, 在 python 下精度也很高.我去搜搜
petelin
2017-07-09 18:49:45 +08:00
@petelin Python 下浮点数都是用双精度存的,所以精度会高一点, 这个时候 99999999999999.99 就开始不精确了
In [38]: 99999999999999.99 + 99999999999999.99
Out[38]: 199999999999999.97

我觉得如果你的系统任何一处能算到这么大的数, 那就不能用了, 如果没有的还是可以的用的, 0.1d 在怎么加,只要小数点后两位也没什么问题.

ps: 都是个人直觉...实际工作还是存分吧, 或者老大说怎么搞就怎么搞 :)
BigBearWatchYou
2017-07-10 21:04:24 +08:00
@petelin IEEE 754 协议规定的,大部分语言里都遵循这个,单精度保证 7 位,双精度保证 15 位
具体计算细节我之前思考过,还挺有意思的。不只是直接 N*lg2,而是整数部分看大小,小数部分看舍入,然后一块计算,但是最后结果也是近似 N*lg2,有空我可以整理一下

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

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

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

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

© 2021 V2EX