java - 将位转换为双精度后,如何在不使用 BigDecimal 的情况下存储实际的浮点/双精度值?
问题描述
根据几个浮点计算器以及我下面的代码,以下 32 位00111111010000000100000110001001的实际浮点值为 (0.750999987125396728515625)。由于它是实际的 Float 值,我应该认为将其存储在 Double 或 Float 中会保留精度和精确值,只要(1)不执行算术(2)使用实际值和(3)值是没有被贬低。那么为什么实际值与 (0.7509999871253967) 的强制转换(示例 1)和文字(示例 2)值不同?
我以这个计算器为例: 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);
}
}
这是输出:
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
解决方案
没有实际的精度损失;问题是您对双打如何转换String
(例如打印时)的错误期望。
m 或 a 的小数部分必须打印多少位?必须至少有一个数字来表示小数部分,除此之外,必须有尽可能多的数字,但只需要将参数值与相邻的 double 类型值唯一区分开来。也就是说,假设 x 是由该方法为有限非零参数 d 生成的十进制表示所表示的精确数学值。那么 d 必须是最接近 x 的 double 值;或者如果两个双精度值同样接近 x,则 d 必须是其中之一,并且 d 的有效位的最低有效位必须为 0。
因此,当double
打印 a 时,它只打印了足够的数字来唯一标识该double
值,而不是将精确值描述为实数所需的位数。
如果您想获得double
所有可能数字的 a 的精确值,new BigDecimal(theDouble).toPlainString()
您就是这样做的——并且,正如您所展示的,它会得到正确的结果。
推荐阅读
- python - 列表中的唯一文件名
- jquery - 如何在 jQuery 中编写 If 语句以减少代码
- mongodb - FindOneAndUpdate 函数不更新数据库
- javascript - JavaScript工厂函数修改闭包范围外的变量
- cypress - 单击元素失败,因为它错误地认为它是不可见的
- mysql - 如何避免在每个 MySql 查询中使用数据库名称
- css - 如何将 SVG 的高度设置为其封闭容器的高度?
- php - PHP:你如何修复第五个有异常对齐的 SQL 项?
- python - Numpy 生成导致分割掩码对角分割的 x,y 坐标
- amazon-web-services - 在从 ec2 实例执行同步或复制操作时删除 s3 存储桶中存在的文件夹中的文件