这里有几个相关的问题。
根据标题,为什么它是一个要求,如果我们指定的变量类型为长或float, double?编译器在编译时不评估变量的类型吗?
Java认为所有的整型字面值为int
-这是为了减少无意的内存浪费的打击?和所有的浮点字面值作为double
-以确保最高的精度?
当你有一个常量时,值之间会有细微的差异,这些差异看起来是一样的,但实际上不是。此外,由于引入了自动装箱,您将得到一个非常不同的结果。
考虑将0.1乘以0.1作为浮点数或作为双精度数并转换为浮点数的结果。
float a = (float) (0.1 * 0.1);
float b = 0.1f * 0.1f;
System.out.println("a= "+new BigDecimal(a));
System.out.println("b= "+new BigDecimal(b));
System.out.println("a == b is " + (a == b));
打印
a= 0.00999999977648258209228515625
b= 0.010000000707805156707763671875
a == b is false
现在比较使用float
或int
进行计算得到的结果。
float a = 33333333f - 11111111f;
float b = 33333333 - 11111111;
System.out.println("a= "+new BigDecimal(a));
System.out.println("b= "+new BigDecimal(b));
System.out.println("a == b is " + (a == b));
打印
a= 22222220
b= 22222222
a == b is false
比较int
和long
long a = 33333333 * 11111111; // overflows
long b = 33333333L * 11111111L;
System.out.println("a= "+new BigDecimal(a));
System.out.println("b= "+new BigDecimal(b));
System.out.println("a == b is " + (a == b));
打印
a= -1846840301
b= 370370362962963
a == b is false
比较double
和long
double a = 333333333333333333L / 333333333L;
double b = 333333333333333333D / 333333333D;
System.out.println("a= "+new BigDecimal(a));
System.out.println("b= "+new BigDecimal(b));
System.out.println("a == b is " + (a == b));
打印
a= 1000000001
b= 1000000000.99999988079071044921875
a == b is false
总之,使用int
, long
, double
或float
与使用其他类型相比,可能会产生不同的结果。
当您要做的不仅仅是一个简单的赋值时,这一点变得很重要。如果你取
float x = 0.1 * 3.0;
如果计算机先以双精度进行乘法运算,然后转换为单精度,或者先将数字转换为单精度,然后再进行乘法运算,这是有区别的。
编辑:不是在0.1和3.0这种明确的情况下,但是如果您的数字变得足够复杂,您将遇到显示float和double之间差异的精度问题。如果它们应该是双精度或浮点数,则向编译器明确说明可以避免歧义。
我认为这只是为了避免混淆。如果没有默认值,编译器如何知道1.5是浮点数或双精度数?至于求值变量,请注意变量=文字
编辑1
关于一些注释,我相信有时您不希望编译器自动将右侧的文字转换为左侧的变量类型。
编辑2
当然还有
public void foo(int bar) {
//...
}
public void foo(long bar) {
//...
}
//... some other method
foo(20); // which foo is called?