-
Notifications
You must be signed in to change notification settings - Fork 45
java float double precision
landon edited this page Aug 27, 2018
·
1 revision
- 输出测试
// 输出8056.0
System.out.println(7600 * 1.06);
// 输出8055.9995
System.out.println(7600 * 1.06f);
// 输出1.0599999E7
System.out.println(10000000 * 1.06f);
// 输出1.06E7
System.out.println(10000000 * 1.06);
7.22 - 7.0 = 0.21999999999999975
7.22f - 7.0f = 0.21999979
4.8 / 6 = 0.7999999999999999
// 输出为true 这也从侧面反映了上面的计算,因为默认的double精度高一些
// 7600 * 1.06计算出来的值更接近于8056
double d1 = 8055.99999999999999999;
double d2 = 8056.0;
System.out.println(d1 == d2);
- 参考
- 总结
- 之所以叫浮点数,就是因为是用科学计数法的形式存储的
- 有些小数在计算机中是无法精确表示的,如0.1/0.2/0.3/0.4...
- 对于小数点后面的数,其实转为二进制的规则是类似的,比如0.01(2进制)
- 小数点后0 * ½ + 1 * ¼ = 0.25
- ½ = 2的-1次方
- ¼ = 2的-2次方
- 可以使用除2取余法和乘2取整法进行10进制整数和10进制小数转换
- BigDecimal的解决方案就是,不使用二进制,而是使用十进制(BigInteger)+小数点位置(scale)来表示小数
- 使用需要注意,通常可以使用public static BigDecimal valueOf(double val)方法
- 即使用字符串作为构造函数
- 对于需要精确答案的计算,不能使用float或者double,BigDecimal允许完全控制舍入,如果业务要求涉及多种舍入方式,使用BigDecimal很方便,如果性能很关键,涉及的数值不大,就可以使用int或者float,如果数值范围没有超过9位十进制数字,可以使用int,如果不超过18位数字,使用long,如果数值可能超过18位,就必须用BigDecimal
- 最终游戏中属性计算相关方案需要和策划确认即可,采用合适的计算方案
- 补充上面的输出,通过ieee754的工具 所以计算出来的值精度不同
1.06#32bit#fraction:1.00001111010111000010100
1.06#64bit#fraction:1.0000111101011100001010001111010111000010100011110110
- 其他
游戏内会碰到一种需求, 就是客户端试穿装备,来回来去拖拽调整,这时候并不需要请求服务器
或者技能下级预览需求,这两种情况都是客户端通过公式计算的
因此存在客户端,服务器计算结果不一致的情况。
当时调了很多次,过程确实很痛苦。
程序对应,也可以规避掉小数,比如把数值乘以10000之类的
这个要看策划要求,看他们要求精度多少