我有一个原始的浮点数,我需要一个原始的双精度浮点数。简单地将浮点数转换为 double 会给我带来奇怪的额外精度。例如:

float temp = 14009.35F;
System.out.println(Float.toString(temp)); // Prints 14009.35
System.out.println(Double.toString((double)temp)); // Prints 14009.349609375

但是,如果我不进行强制转换,而是将浮点数输出为字符串,并将该字符串解析为双精度数,我会得到我想要的:

System.out.println(Double.toString(Double.parseDouble(Float.toString(temp))));
// Prints 14009.35

有没有比往返 String 更好的方法?

有帮助吗?

解决方案

这不是你的真正的获得额外的精度 - 这是浮子没有准确地代表你瞄准了原本数量。双准确表示原始浮子; toString是示出“额外”的数据,其已存在。

例如(这些数字是不正确的,我只是胡编)假设你有:

float f = 0.1F;
double d = f;

然后f的值可能正是0.100000234523。 d将有完全一样的价值,但是当你将它转换为字符串,将“信任”,它是精确到一个更高的精度,所以不会四舍五入早,你会看到这是“额外数字”已经存在,但是从你隐藏的。

当您转换为字符串和背部,你和一个双值更接近字符串值比原来的浮动是结束了 - 但这只是良好的如果的你真的相信该字符串值是什么,你真正想要的。

您确定浮点/双精度是合适的类型在这里使用的,而不是BigDecimal?如果你想使用具有精确的十进制值(例如钱)的数字,然后BigDecimal是一个比较合适类型IMO。

其他提示

我找到转换为二进制表示更容易抓住这个问题。

float f = 0.27f;
double d2 = (double) f;
double d3 = 0.27d;

System.out.println(Integer.toBinaryString(Float.floatToRawIntBits(f)));
System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d2)));
System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(d3)));

可以看到浮子被扩展到双通过加入0到结束,但0.27双表示是“更精确”的,因此该问题。

   111110100010100011110101110001
11111111010001010001111010111000100000000000000000000000000000
11111111010001010001111010111000010100011110101110000101001000

这是由于合同 Float.toString(float), 其中部分内容是:

必须打印几位数字[…]?必须至少有一个数字来代表小部分,除此之外, 但只有那么多, 需要更多的数字,以唯一将参数值与类型浮子的相邻值区分开。 也就是说,假设x是该方法为有限的非零参数f所产生的十进制表示所示的确切数学值。然后f必须是最接近x的浮子值;或者,如果两个浮点值同样接近x,则F必须是其中之一,而F的最小显着位必须为0。

我遇到这个问题今天不能使用重构为BigDecimal的,因为这个项目确实是巨大的。然而,我发现溶液中使用

Float result = new Float(5623.23)
Double doubleResult = new FloatingDecimal(result.floatValue()).doubleValue()

和其工作原理。

请注意,调用result.doubleValue()返回5623.22998046875

但是调用doubleResult.doubleValue()正确返回5623.23

但我不能完全肯定,如果它是一个正确的解决方案。

使用一个BigDecimal代替float / double。有很多数字不能被表示为二进制浮点数(例如,0.1)。所以,你要么必须始终轮结果到已知精度或使用BigDecimal

请参阅 http://en.wikipedia.org/wiki/Floating_point 了解详情

我发现了以下解决方案:

public static Double getFloatAsDouble(Float fValue) {
    return Double.valueOf(fValue.toString());
}

如果您使用的浮动双击的而不是浮动双击的使用以下命令:

public static double getFloatAsDouble(float value) {
    return Double.valueOf(Float.valueOf(value).toString()).doubleValue();
}

花车,本质上是不准确的,总是有整齐的圆“的问题”。如果精度是非常重要的,那么你可以考虑重构你的应用程序中使用十进制或BigDecimal的。

是,浮体在计算上比在处理器的支持,因为的小数更快。但是,你想快速或准确的?

有关的信息这来自下项目48 - 避免浮点和双精度时是必需的,有效的Java第二版由Joshua布洛赫精确值。这本书是果酱挤满了好东西,绝对值得一看。

工作的呢?

float flt = 145.664454;

Double dbl = 0.0;
dbl += flt;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top