【发布时间】:2022-09-24 05:10:37
【问题描述】:
我想将 Java 双精度(IEEE754 双精度 64 位)转换为它的二进制表示,修改 21 个最低有效位以将一些元数据嵌入到双精度中,将其转换回双精度,并保留 6 位小数精确。
约束:我将处理的双精度值将始终在 [-180, 180] 的范围内。
例子:
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 位双精度如何用二进制表示,以及是否有任何其他方法可以修改双精度位而不丢失所需的精度。
非常感谢任何输入!
-
你的计算基本上是正确的。尾数是 52 位,因此砍掉 21 会留下 31 位,即大约 9 位。您清楚地保留了 8 位精度(145.88160)。请记住,“6 位小数”并不意味着“小数点后 6 位”。它从第一个有效数字开始。
-
在我看来很好。您的 \"before\" 和 \"after\" 数字是相同的,保留 7 个小数位。使用您的策略,您可以稍微增加或减少数字,当您这样做时,它总是有可能超过 0.000001 的倍数。所以总是有可能打印的前六位小数会不同(就像这里发生的那样),但是“之前”和“之后”数字之间的差异总是远远小于 0.000001。
-
正如我之前解释的,更改最低有效 21 位可以非常轻微地增加或减少数字,使其超过 0.0000001 的倍数。换句话说,它可以改变数字的小数扩展的前 7 位中的任何一个;你绝对无能为力。
-
@CoderGuy 可以“修改”吗多于要嵌入的 21 个最低有效位指定的 21 位元数据转换为双精度,将其转换回双精度,并保持 6 位小数的精度\"?示例将 x 设为 1 in 1100 0000 0110 0010 0011 1100 0011 0110 0001 0101 x110 0010 1001 1000 0110 0101。
-
@CoderGuy IOWs,取您的值并以十进制形式 sddd.dddddd5 形成中点,并调整该值的低 21 位。取中点可以减少有效负载影响 sddd.dddddd 十进制值的机会。我思考它可能适用于
|x| < 256的所有double x,但尚未完成分析。会心为什么你想这样做也会有帮助。有必要难吗探测值改变了吗?
标签: java floating-point double precision floating-accuracy