3

我有关于双精度的问题。当浮点值传递给双精度时,我会得到一些不同的结果。例如

float f= 54.23f;
double d1 = f;
System.out.println(d1);

输出为 54.22999954223633。有人可以解释这种行为背后的原因。是否像 double 默认为 14 位小数精度。

4

5 回答 5

6

相同的值打印不同floatdouble因为 Java 规范要求打印尽可能多的数字,以区分相同类型的相邻可表示值的值(根据我在此处的回答,请参阅链接文档以获取更精确的定义)。

由于float用于表示值的位更少,因此值也更少,因此它们之间的间距更大,并且您不需要那么多数字来区分它们。当您将值放入 adouble并打印时,Java 规则要求打印更多的数字,以便将该值与附近的double值区分开来。该println函数不知道该值最初来自 afloat并且不包含尽可能多的信息以适合 a double

54.23f正好是 54.229999542236328125(十六进制,0x1.b1d70ap+5)。float刚好低于和高于此值的值为 54.2299957275390625 (0x1.b1d708p+5) 和 54.23000335693359375 (0x1.b1d70cp+5)。如您所见,打印“54.229999”会将值与 54.229995... 和 54.23... 区分开来。但是,double正下方和正上方的值54.23f是 54.22999954223632101957264239899814128875732421875 和 54.22999954223633523042735760100185871124267578125。要区分值,您需要“54.22999954223633”。

于 2013-03-21T14:52:43.280 回答
0

这是由于内部代表
浮点数通常作为符号位、指数字段和有效数(尾数)从左到右打包到计算机数据中。

这称为准确性问题
浮点数不能精确地表示所有实数,浮点运算也不能精确地表示真正的算术运算,这一事实导致了许多令人惊讶的情况。这与计算机通常表示数字的有限精度有关。

这不成问题。这就是双重的工作方式。您不必处理它并关心它。double 的精度就足够了。想一想,你的数字和预期结果之间的差异在小数点后的第 14 位。

如果您需要任意良好的精度,请使用java.math.BigDecimal该类。

或者,如果您仍想使用双精度。这样做:

double d = 5.5451521841;
NumberFormat nf = new DecimalFormat("##.###");
System.out.println(nf.format(d));

如有任何疑问,请告诉我。

于 2013-03-21T13:50:35.760 回答
0

实际上这只是关于不同的视觉表示或将浮点/双精度转换为字符串。让我们看一下内部二进制表示

    float f = 0.23f;
    double d = f;
    System.out.println(Integer.toBinaryString(Float.floatToIntBits(f)));
    System.out.println(Long.toBinaryString(Double.doubleToLongBits(d)));

输出

111110011010111000010100011111
11111111001101011100001010001111100000000000000000000000000000

这意味着f转换为d1没有任何失真,有效数字相同

于 2013-03-21T14:40:54.913 回答
0

这是因为 float 隐藏了多余的小数,而 double 显示了它们。双精度将非常精确地表示实际数字并显示更多数字。

尝试这个:

System.out.println(f.doubleValue()); (当然首先需要使它成为一个浮点数

如您所见,信息就在那里,只是四舍五入。希望这可以帮助

于 2013-03-21T13:47:30.540 回答
-1

doublefloat以不同的格式表示数字。

因此,您一定会发现某些数字可以完美地以一种格式存储,但不能以另一种格式存储。您碰巧找到了一个正确地适合 afloat但不适合exactly`double。

当使用两种不同的格式化程序时,也会出现此问题。

于 2013-03-21T13:46:47.157 回答