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

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

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

6429 次点击
所在节点    数学
25 条回复
petelin
2017-07-07 17:34:28 +08:00
加一个条件, 参加计算的小数,标度最大为 2, 也就是说不会有 0.001 这种
coderfox
2017-07-07 17:41:07 +08:00
是要存金钱吗?

位数确定的小数,在不超过数据类型范围的情况下还是建议存成整数。
一方面是肯定不会出现精度损失;
另一方面是整型的计算、序列化、反序列化都比浮点数快。
choury
2017-07-07 17:42:32 +08:00
直接乘以 100 存成整数多好
h4x3rotab
2017-07-07 17:56:59 +08:00
原因是浮点表示实际是二进制小数,很多十进制小数在二进制下就是循环小数。资金要用 fixed 表示。
littleylv
2017-07-07 18:00:39 +08:00
现在一般建议价格等金额的数据存整数
af463419014
2017-07-07 18:07:36 +08:00
用 decimal,不会出现浮点数计算的误差
snnn
2017-07-07 18:12:16 +08:00
看你要做什么操作了。只是加减法就还好
archer2ee
2017-07-07 18:13:27 +08:00
如果是金钱的话,存分!!我做支付用 bigdecimal 也感觉各种麻烦。float 就是禁区了。
BigBearWatchYou
2017-07-07 18:52:49 +08:00
你不妨试试 System.out.println(999999.99f);

建议:
1.float 最多保证 7 位有效数字,如果超过了,就不要用 float,而是使用 bigdecimal (这里的有效数字指:从该数高位的第一个非零数字起,直到低位末尾的小数非零数字或个位止的数字)
2.因为 bigdecimal 的性能不好,如果是跟钱有关,只可能有两位小数,那建议直接用 long 存分,在需要显示的地方格式化
BigBearWatchYou
2017-07-07 18:57:10 +08:00
而且如果要进行四则运算,因为有对阶过程,float 连 7 位有效数字的精度也无法保证
bear2017
2017-07-07 21:26:30 +08:00
是涉及到钱吗?涉及钱的话用分做单位,显示客户端统一除 100。不要用 float,会有问题的。
rrfeng
2017-07-07 21:59:06 +08:00
这个直接 * 100 存整数。
只要是小数,不管你几位总会出现误差的。
gogohigh
2017-07-07 22:09:04 +08:00
不行。float 只是近似值,用 String 或者*100 存整形
xenme
2017-07-07 22:21:17 +08:00
歪个楼:
上面好多出现一分钱抢购的是不是都是你们存分,然后计算的时候没有乘以 100,直接卖了啊?
akira
2017-07-07 22:21:35 +08:00
没有问题。
mingyun
2017-07-07 23:06:32 +08:00
参考微信用分做单位
zoudm
2017-07-07 23:48:31 +08:00
一个经典样例。
#include <stdio.h>
int main() {
float t = 0.1;
float sum = 0;
for (int i = 0; i < 100000; i++) {
sum += t;
}
printf("sum: %f\n", sum);
return 0;
}

gcc -o testfloat testfloat.c
./testfloat
sum: 9998.556641

准确结果应该为 10000,实际为 9998.556641
hjc4869
2017-07-08 00:52:11 +08:00
问题很大,楼主的需求明显是要用定点数。
ssynhtn
2017-07-08 07:59:20 +08:00
有,较大的数,float 连整数都无法全部覆盖
chinawrj
2017-07-08 10:24:18 +08:00
不要用浮点,不要用浮点,不要用浮点!直接倍数之后用整型!或者有金融 math 库

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

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

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

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

© 2021 V2EX