双(IEEE754双精度64位)二进制表示



我想将Java双精度(IEEE754双精度64位(转换为其二进制表示,修改21个最低有效位以将一些元数据嵌入双精度中,将其转换回双精度,并保持小数点后6位的精度。

约束:我将要处理的双值将始终在[-180180]的范围内。

示例:

Double value: -145.88160204733163
IEEE754 Double precision 64-bit binary:
1100 0000 0110 0010 0011 1100 0011 0110 0001 0101 0111 1111 0010 1100 0000 1000
IEEE754 Double precision 64-bit binary with 21 least significant bits modified:
1100 0000 0110 0010 0011 1100 0011 0110 0001 0101 0110 0010 1001 1000 0110 0101
Double value with 21 least significant bits modified:
-145.88160199410336

我知道符号需要保留1位,指数需要保留11位,-180和180之间的整数需要保留尾数中的7位。由于我需要保持小数点后6位的精度,我认为有效数字的额外24位就足以保持小数点前6位的精确度(由于每个数字需要3.32位,我在这里的理解可能不正确(,所以我可以使用21个最低有效位来嵌入元数据。

我想知道我在哪里误解了64位双精度是如何用二进制表示的,以及是否有其他方法可以在不损失所需精度的情况下修改双精度的位。

非常感谢您的任何意见!

当OP代码更改IEEE754双精度64位值的21个最低有效位时,结果是大于或小于原始值。有时这种变化,即使Double中只有1个最低有效位的变化就足以在打印到小数点后6位时改变输出。


考虑一个十进制值ddd.dddddd5,其中d是数字0-9。我们有一个介于两个dd.ddddd值之间的值。该值在中很少被精确地编码为Double*1。使用附近的Double,当打印小数点后6位时,四舍五入到最接近的0.000001。输出为ddd.dddddd或0.000001以上,具体取决于最近的Double是否比ddd.ddDDD5稍大或稍小。

如果它打印为ddd.dddddd,并且有效载荷超过了原始的21位,甚至只多了1个最低有效位,则该值会多打印0.000001。与wise一样,如果它打印为ddd.dddddd+0.000001,并且有效载荷较小,则它打印为DD.dddddd.

为了实现OP的目标,我们可以将值四舍五入到最接近的0.000001,以使它们远离ddd.dddd5边界。然后,我们可以成功地替换至少21个比特,正如OP所描述和推理的那样。

舍入是棘手的,因为许多舍入技术不正确地处理边缘条件,例如较差的round(x*1000000.0)/1000000.0。这里的问题是x * 1000000.0并不总是形成精确的乘积,这对于边缘情况至关重要。

我不太精通java,但打印到小数点后6位并转换回Double就可以了。


注意,这个答案与我的评论不同。在这种情况下,我专注于不更改值ddd.ddddxxxxxx的d位数(如果打印到许多小数位(。正如我现在看到的,当打印到小数点后6位时,OP想要相同的输出。

*1所有Double,当精确地表达时,都有0.0、0.5、0.25、0.75、0.125、0.375、0.625、0.875…的小数部分,而不是0.1、0.2、0.3、0.4、0.6…

最新更新