简体   繁体   English

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

[英]After converting bits to Double, how to store actual float/double value without using BigDecimal?

According to several floating point calculators and as well as my code below, the following 32 bits 00111111010000000100000110001001 has an actual Floating Point value of (0.750999987125396728515625).根据几个浮点计算器以及我下面的代码,以下 32 位00111111010000000100000110001001的实际浮点值为 (0.750999987125396728515625)。 Since it is the actual Float value, I should think storing it in a Double or Float would retain the precision and exact value so long as (1) no arithmetic is performed (2) the actual value is used and (3) the value is not down-casted.由于它是实际的 Float 值,我应该认为将其存储在 Double 或 Float 中会保留精度和精确值,只要(1)不执行算术(2)使用实际值和(3)值是没有被贬低。 So why is the actual value different from the casted (example 1) and literal (example 2) value of (0.7509999871253967)?那么为什么实际值与 (0.7509999871253967) 的强制转换(示例 1)和文字(示例 2)值不同?

I used this calculator as an example: https://www.h-schmidt.net/FloatConverter/IEEE754.html我以这个计算器为例: https://www.h-schmidt.net/FloatConverter/IEEE754.html

在此处输入图像描述

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);
    }
}

Here is the output:这是 output:

      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

There is no actual loss of precision;没有实际的精度损失; the issue is your incorrect expectations about how doubles are converted to String (eg when printed).问题是您对如何将双打转换为String (例如打印时)的错误期望。

From the documentation of Double.toString :Double.toString的文档中

How many digits must be printed for the fractional part of m or a? m 或 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.必须至少有一个数字来表示小数部分,除此之外,必须有尽可能多的数字,但仅能将参数值与相邻的 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.也就是说,假设 x 是由该方法为有限非零参数 d 生成的十进制表示所表示的精确数学值。 Then d must be the double value nearest to x;那么 d 必须是最接近 x 的 double 值; 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.或者如果两个双精度值同样接近 x,则 d 必须是其中之一,并且 d 的有效位的最低有效位必须为 0。

So when a double gets printed, it is printed only with enough digits to uniquely identify that double value, not with the number of digits needed to describe the precise value as a real number.因此,当一个double被打印时,它只打印了足够的数字来唯一标识该double值,而不是用将精确值描述为实数所需的位数。

If you want to get the precise value of a double with all possible digits, new BigDecimal(theDouble).toPlainString() is how you do it -- and, as you demonstrate, it gets the correct result.如果您想获得具有所有可能数字的double精度值,那么new BigDecimal(theDouble).toPlainString()就是您的方法 - 而且,正如您所演示的,它会得到正确的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM