java - 将位转换为 double 后,如何在不使用 BigDecimal 的情况下存储实际的浮点/ double 值?

标签 java floating-point bigdecimal ieee-754 single-precision

根据几个浮点计算器以及我下面的代码,以下 32 位 00111111010000000100000110001001 的实际浮点值为 (0.750999987125396728515625)。由于它是实际的 Float 值,我应该认为将其存储在 Double 或 Float 中会保留精度和精确值,只要(1)不执行算术(2)使用实际值和(3)值是没有被贬低。那么为什么实际值与 (0.7509999871253967) 的强制转换(示例 1)和文字(示例 2)值不同?

我以这个计算器为例: https://www.h-schmidt.net/FloatConverter/IEEE754.html

enter image description here

import java.math.BigInteger;
import java.math.BigDecimal;

public class MyClass {
    public static void main(String args[]) {
      int myInteger = new BigInteger("00111111010000000100000110001001", 2).intValue();
      Double myDouble = (double) Float.intBitsToFloat(myInteger);
      String myBidDecimal = new BigDecimal(myDouble).toPlainString();

      System.out.println("      bits converted to integer: 00111111010000000100000110001001 = " + myInteger);
      System.out.println("    integer converted to double: " + myDouble);
      System.out.println(" double converted to BigDecimal: " + myBidDecimal);

      Double myDouble2 = 0.750999987125396728515625;
      String myBidDecimal2 = new BigDecimal(myDouble2).toPlainString();

      System.out.println("");
      System.out.println("       Ignore the binary string: ");
      System.out.println("            double from literal: " + myDouble2);
      System.out.println(" double converted to BigDecimal: " + myBidDecimal2);
    }
}

这是输出:

      bits converted to integer: 00111111010000000100000110001001 = 1061175689
    integer converted to double: 0.7509999871253967
 double converted to BigDecimal: 0.750999987125396728515625

       Ignore the binary string: 
            double from literal: 0.7509999871253967
 double converted to BigDecimal: 0.750999987125396728515625

最佳答案

没有实际的精度损失;问题是您对如何将 double 转换为 String(例如打印时)的错误期望。

来自 the documentation of Double.toString :

How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type double. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument d. Then d must be the double value nearest to x; or if two double values are equally close to x, then d must be one of them and the least significant bit of the significand of d must be 0.

所以当 double 被打印时,它只打印足够的数字来唯一标识该 double 值,而不是描述精确值所需的位数作为一个实数。

如果您想获得具有所有可能数字的 double 的精确值,new BigDecimal(theDouble).toPlainString() 就是您的方法 - 并且,正如您所演示的,它得到了正确的结果。

关于java - 将位转换为 double 后,如何在不使用 BigDecimal 的情况下存储实际的浮点/ double 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62224816/

相关文章:

java - 大十进制下溢

java - "Math.abs()"的性能是否优于 "if"的表达式?

c++ - 随机浮点发生器

java - 我如何在 JFrame 上添加 "undraw"内容?

c++ - 不能将 float 数组传出函数

C# 浮点表达式 : strange behavior when casting the result float to int

java - 在Java中使用BigDecimal计算最多200位十进制数字的PI数

Java 大十进制问题

java - 升级到 tomcat 8.5 时使用自定义 keystore 和 jsse 实现

java - 如何在 super.xxx() 之后使用 Javassist 插入代码