尝试将双精度前缀数转换为十进制



我正在尝试将双精度数字转换为十进制数。 例如,双精度和字节中的数字 22 是:

[0] 0
[1] 0
[2] 0
[3] 0
[4] 0
[5] 0
[6] 54
[7] 64

现在我尝试将这些值再次转换为 22 :

  ByteBuffer buffer = ByteBuffer.wrap(data);
  long l = buffer.getLong();
  long b = Double.doubleToLongBits(l);

但结果是完全错误的:4.6688606E18这个数字是多少?请帮忙,我完全糊涂了!

根据 IEEE 标准 754 的双精度:

存储为双精度的任何值都需要 64 位,格式如下表所示:

63符号(0 = 正,1 = 负)

62 到 52指数,偏差为 1023

51 到 0数字 1.f 的分数 f

现在我应该如何将双精度转换为数字以再次得到 22 ? 所有这些答案都是错误的

我不确定您要执行哪种转换(当您说"转换为十进制"时,您想要的输出格式/类是什么?

然而,我读到标题的第一个想法是 BigDecimal 将是一个有效的表示形式。 因此,第一种方法是执行以下操作:

double d = ...; // your input number
BigDecimal b = new BigDecimal(d);

也就是说,如果你想转换为十进制,那么大概是因为 d 的值存在浮动点/舍入问题,当它基于 d 构造时,它仍然存在于BigDecimal表示中。

解决此问题的最佳方法是从一开始就使用BigDecimals,使用其String构造函数 - 因此不会有任何浮点舍入实例。 如果出于某种原因这不是一个选项,则可以将double转换为字符串,以便它能够解决许多浮点舍入问题:

String strRep = Double.toString(d);
BigDecimal b = new BigDecimal(strRep);

你可以编写简单的测试(用JUnit):

double initial = 22.0;
long bits = Double.doubleToLongBits(initial);
double converted = Double.longBitsToDouble(bits);
assertEquals(Double.valueOf(initial), Double.valueOf(converted));

如果这有效 - 检查您是否有 22 的正确字节表示形式(正确的表示形式将在 bits 变量处)。

最新更新