2

对所有人来说,这可能是一个简单的问题,但它让我的脑海里出现了一个问题,“为什么会这样?”

正如您在下面的代码中看到的那样,我已经声明了一个float变量并为其分配了一个值。当这段代码被编译和解释时,我会得到一个错误,possible loss of precision因为浮点常量的java解释器的默认数据类型是双精度的。

查询 1:我想知道,当我的浮动常量可以容纳 float 提供的字节数时,我为什么要在我的应用程序中浪费内存以获得双精度。

查询 2:现在如果我指定我将得到输出,但现在为我的变量float a = 3.1415f ;分配了多少内存。a

float a = 3.1415 ;
System.out.println("Value of a:"+a);

我真的很想了解这个hack,为什么会这样?

4

5 回答 5

2

查询 1:我想知道,当我的浮动常量可以容纳 float 提供的字节数时,我为什么要在我的应用程序中浪费内存以获得双精度。

这只是浮点文字默认为double. 从JLS 的第 3.10.2 节

如果浮点文字以 ASCII 字母 F 或 f 为后缀,则它的类型为 float;否则,它的类型是双精度的,并且可以选择以 ASCII 字母 D 或 d 为后缀(第 4.2.3 节)。

您需要决定您想要哪种类型,并编写适当的文字。您几乎可以肯定不应该根据您指定的数字位数来选择数据类型 - 并且请注意,仅仅因为float可以保持一定数量的小数位数的准确性并不意味着它可以准确地表示具有那么多的数字有效数字。例如,没有二进制浮点类型可以精确地表示 0.1,就像您不能将“三分之一”写为有限十进制数一样。

作为旁注,我个人喜欢d明确添加 for double,只是为了清楚起见。

下一个:

查询 2:现在如果我指定 float a = 3.1415f ;我将得到输出,但现在为我的变量分配了多少内存。

4 个字节,因为它是一个float.

于 2013-08-22T13:20:01.900 回答
1

“查询 1:我想知道,当我的浮动常量可以容纳 float 提供的字节数时,我为什么要在我的应用程序中浪费内存以获得双倍内存。”

这包含了一个错误的假设。float 和 double 都不能真正存储您的价值:

float: 3.141499996185302734375
double: 3.141500000000000181188397618825547397136688232421875

两者都是近似值,但双精度比浮点数更接近。

如果您不打算考虑文字所需的精度,则使用 double 会更安全,因此它是适当的默认值。如果您已经分析了浮点舍入误差的影响,并确定浮点是可以接受的,那么您可以并且应该将其设为浮点字面量。

于 2013-08-23T01:50:06.560 回答
0

查询 1:因为浮点计算几乎总是涉及近似值。doubletypes 具有更高的浮点精度(双精度),因此它减少了由于近似而丢失任何数据的机会。我认为这可能是将任何浮点文字视为双精度的原因。

查询 2:对于这两种情况,您的a变量都是 32 位大小的(请查看此处的浮点部分)。在里面 -

float a = 3.1414;

语句,该值被强制转换为浮点数,这称为缩小转换。Java 不允许这样做,但它允许相反的扩展转换。

于 2013-08-22T13:19:21.247 回答
0

按照规范中的定义,浮点数是 32 位 IEEE 754 值,因此它占用 4 个字节。本文档解释了默认设置和推理:http ://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html 。Sun/Oracle 的建议是,如果不需要 double 的精度,并且内存是一个问题,请像您所做的那样使用 float。

于 2013-08-22T13:20:07.190 回答
0

让我回答一个问题:

为什么这个小代码片段打印false而不是true

float a = 3.1415;
double b = 3.1415;
double c = a;
System.out.println((b==c));

... 知道了?确切地!

然而这确实不是全部逻辑,因为 0.1f 和 0.1 在二进制表示中是不同的数字,但 0.5f 和 0.5 是相同的,编译器应该允许你声明 float f = 0.5; 但它不会评估每个数字是否“适合”浮动或需要一个没有精度损失的双精度数......它只是假设绝大多数人都会丢失精度,这是正确的。

于 2013-08-23T15:25:03.347 回答