我想将我从数据库中获取的经度和纬度转换为字符串。字符串是正确的,当我尝试将其转换为double时,它也是正确的。但是,当我将double或字符串值(我已尝试过两者)转换为浮点值时,最后一个小数将四舍五入。
字符串或双精度值为59.858139 转换为浮动是59.85814
我已经尝试了一切,这是一个绝望的例子:)
private float ConvertToFloat(double d)
{
float f = 00.000000f;
f = (float) d;
return f;
}
答案 0 :(得分:7)
你知道双打比漂浮物更精确,并且漂浮得更圆,对吧?这是预期的行为。在这种情况下,将double转换为float是没有意义的。
这是让你思考正确方向的东西......
Double.doubleToRawLongBits(long value);
Float.intBitsToFloat(int bits);
双打不能适应int,他们必须适应长。它的大小真的是两倍,即使用字符串调整位也不会有任何好处。
答案 1 :(得分:3)
1。 float
只有 24位精度,不足来保存你的数字位数纬度和经度。
2。四舍五入是由数字的大小决定的。因此,如果您需要浮点数,请使用double
,或使用BigDecimal
答案 2 :(得分:1)
我们从您的十进制数59.858139
将该数字转换为二进制数:111011.11011011101011101111111101011100011011000001000110100001000100...
即。数字是二进制的无限分数。不可能完全代表它。 (与无法用十进制数表示1/3的方式相同)
将数字重写为某种形式的二进制科学记数法:
10 ^ 101 * 1.1101111011011101011101111111101011100011011000001000110100001000100...
请记住,这仍然是二进制的,因此10 ^ 101
对应于十进制表示法中的2 ^ 5
。
现在......浮点值可以在尾数中存储23位。如果我们使用“舍入到最近”舍入模式将其四舍五入,我们得到:
10 ^ 101 * 1.11011110110111010111100
等于:
111011.110110111010111100
这是可以适合float数据类型的所有精度。现在将其转换回十进制:
59.8581390380859375
实际上看起来非常接近59.858139 ......但那只是运气。如果我们将第二个最接近的浮点值转换为二进制值会发生什么?
111011.110110111010111011 = 59.858135223388671875
所以基本上分辨率约为0.000004
。
所以我们从浮点值中真正知道的是这个数字是这样的:59.858139
±0.000002
它也可以是59.858137
或59.858141
。
由于最后一位数字相当不确定,我猜测打印代码足够聪明,可以理解最后一位数超出浮点值的精度,因此,该值四舍五入为59.85814
。
顺便说一句,如果你(像我一样)懒得手动转换二进制和小数部分,你可以使用this converter。如果您想了解有关浮点系统详细信息的更多信息,the wikipedia page for floating point representation是一个很好的资源。