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

问题描述 投票:1回答:1

根据一些浮点计算器和下面的代码,以下32位00111111010000000100000110001001的实际浮点值为(0.750999987125396728515625)。由于它是实际的Float值,因此我认为只要将(1)不执行任何算术运算(2)使用实际值和(3)将该值存储在Double或Float中就可以保留精度和精确值。不灰心。那么,为什么实际值与(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
java floating-point bigdecimal ieee-754 single-precision
1个回答
0
投票

没有实际的精度损失;问题是您对双精度如何转换为String(例如,在打印时)有不正确的期望。

来自the documentation of Double.toString

m或a的小数部分必须打印多少个数字?必须有至少一位数字来表示小数部分,并且除此数字外,还必须要有多少个数字才能唯一地将参数值与相邻类型double的值区分开来,但要多多少少。也就是说,假设x是由该方法针对有限的非零参数d生成的十进制表示形式表示的精确数学值。则d必须是最接近x的double值;或者,如果两个双精度值都相等地接近于x,则d必须是其中之一,并且d的有效位的最低有效位必须为0。

因此,当打印Double.toString时,仅以足以唯一标识double值的位数打印,而没有用将精确值描述为实数所需的位数。

如果要获得具有所有可能数字的double的精确值,则double是您的操作方式-并且如您所演示的,它将获得正确的结果。

© www.soinside.com 2019 - 2024. All rights reserved.