我有一个网络应用程序和搜索是由ElasticSearch提供的。
我使用ScriptEngine计算Java中的小数值:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
System.out.println("12*0.0254 = " + engine.eval("12*0.0254"));//0.30479999999999996
System.out.println("12000*0.0000254 = " + engine.eval("12000*0.0000254"));//0.3048如注释中的SOP输出所示,对于相同的输入,输出以不同的方式舍入。
在UI中,我使用了JavaScript的内置eval()函数,这与不一致的Java输出不匹配。
在Java中获得一致和正确的表达式结果的方法是什么,即12 * 0.0254应该总是计算为0.3048而不是0.30479999999999996?
发布于 2022-01-20 10:24:25
仅仅因为两个表达式在数学上是等价的,并不意味着它们在给定的机器算法中计算到相同的值。
虚拟机结合了IEEE二进制浮点算法标准(ANSI/IEEE )中指定的浮点算法的子集。754-1985年,纽约)。
2.8.1.Java虚拟机浮点算法与IEEE 754
> Java虚拟机支持的浮点算法与IEEE 754标准之间的主要区别是:
Java虚拟机的浮点操作不会抛出>异常、陷阱或以其他方式向IEEE 754发出信号:>无效操作、除以零、溢出、下溢或不精确。>Java虚拟机没有信令NaN值。
Java虚拟机不支持IEEE 754信令浮点比较.
Java虚拟机的舍入操作总是使用IEEE 754 >圆到最近的模式。不精确的结果四舍五入到最近的>可表示的值,而领带以零最不重要的位表示值。这是IEEE 754默认模式。但是Java虚拟机>指令将浮点类型的值转换为接近于零的>整型值。Java虚拟机没有提供任何方法来更改浮点舍入模式.
Java虚拟机既不支持IEEE 754单扩展格式,也不支持双扩展格式,除非双扩展和双扩展指数值集可以说支持单个扩展格式。可任意支持的浮点扩展指数和双扩展指数值集不符合IEEE 754扩展格式的值: IEEE 754扩展格式要求扩展精度和扩展指数范围。
资料来源:https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-2.html#jvms-2.8.1.
在JavaScript中,我得到与您相同的结果(https://jsfiddle.net/,97.0b5 (64位)):
console.log(12*0.0254);
console.log(12000*0.0000254);0.30479999999999996
0.3048也许您的GUI框架适用四舍五入?
您可以在Java中将输出格式化为一定数量的小数位,如下所示:
DecimalFormat df = new DecimalFormat("#.#####");
System.out.println(df.format(12*0.0254));
System.out.println(df.format(12000*0.0000254));https://stackoverflow.com/questions/70781378
复制相似问题