存储在浮点数中时,java 如何舍入整数

Eri*_*ren 3 java floating-point numbers rounding

这是一个经典问题:您的遗留代码在真正应该使用 n 整数时使用了浮点数。但是,更改代码中该变量(或多个)的每个实例的成本很高。因此,您需要编写自己的舍入函数,该函数采用一堆参数来提高准确性并转换为整数。

所以,基本的问题是,当浮点数在 java 中生成时,它们如何舍入?经典的例子是 0.1,通常被引用为四舍五入到 0.0999999999998(或类似的东西)。但是,当在 Java 中给定一个整数时,浮点数是否总是向下舍入到它可以表示的下一个值?它是否四舍五入它的内部尾数以有效地舍入其绝对值?或者它只是选择整数和新浮点数之间误差最小的值?

Float.parseFloat(String)当 String 是一个整数时调用时的行为也不同"1234567890"吗?当 String 是一个比 Float 可以存储的精度更高的浮点时,行为是否也相同。

请注意,我使用浮点数或引用 Float,我将它们与 Double 互换使用。与 integer 和 long 相同。

Pas*_*uoq 5

浮点数在java中如何四舍五入?

Java的截断(舍入到零),当您使用结构(int) d,其中d有型doublefloat。如果需要四舍五入到最接近的整数,可以使用以下行:

int a = (int) Math.round(d);
Run Code Online (Sandbox Code Playgroud)

经典的例子是 0.1,通常被引用为四舍五入到 0.0999999999998(或类似的东西)。

您提到的问题不存在于整数中,整数完全可以表示为double(对于 -2 53和 2 53之间的那些)。如果您四舍五入的数字来自先前的计算,这些计算应该产生一个整数,但由于浮点舍入错误而可能没有产生,那么(int) Math.round(d)可能是您应该使用的解决方案。这意味着只要累积误差不超过 0.5,您就会得到正确的整数。

您的遗留代码在真正应该使用 n 整数时使用了浮点数。但是,更改代码中该变量(或多个)的每个实例的成本很高。

如果产生的计算的double d仅仅是计算+-*与其它整数,产生之间-2中间结果53和2 53,则d自动地包含一个整数(它是精确的,因为所涉及的浮点计算是精确的,并且它是一个整数,因为确切的结果是一个整数),您可以使用更简单的(int) d. 另一方面,如果涉及除法或非整数操作数,则不应轻易更改 的类型d,因为它会改变这些计算的结果。

Float.parseFloat(String)当 String 是一个整数时调用时的行为也不同"1234567890"吗?

这将产生 a ,float其值是最接近有理数 1234567890 的可表示单精度值1234567936.0f。这恰好是。

当 String 是一个比 Float 可以存储的精度更高的浮点时,行为是否也相同。

从技术上讲,“0.1”比Float可以存储的精度更高。此外,从技术上讲,前面的示例 1234567890 也比Float可以存储的精度更高。行为是相同的:Float.parseFloat("0.1")产生最接近float有理数 0.1。

  • Java 语言规范,[5.1.2. 扩大原始转换](http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.2) 说“从 int 到 float,或从long 到 float 或 long 到 double 可能会导致精度损失——也就是说,结果可能会丢失值的一些最低有效位。在这种情况下,生成的浮点值将是正确舍入的版本整数值,使用 IEEE 754 舍入到最近模式(第 4.2.4 节)。” (2认同)