具有整数类型的double / float比较(关系运算符)的精度是多少?
据我所知,不建议在任何比较中使用浮点数。但到目前为止,允许此操作,这是一个问题:
int x = 90;
float y = 90.00_001f;
if (x < y) {
System.out.println("it works!"); // gets printed
}
// now just add one zero to lessen the precision a bit...
int x = 90;
float y = 90.000_001f;
if (x < y) {
System.out.println("it works!"); // not printed
}
答案 0 :(得分:3)
这里的问题不是与整数的比较,而是精度为float
本身。
指定float(或double)文字时,可以指定任意数量的小数位数;但这并不意味着编译代码时将保留精度。
例如,以下所有内容都具有相同的值:
90.f
90.000_001f
90.00000000000000000000000000000000000000000000000000000000000000001f
因此第二次比较失败的原因是90.000_001f
等于90.f
;这等于将90
扩展为float
的价值。
答案 1 :(得分:0)
IEEE 754单精度浮点的精度在6到9个有效十进制数字之间(source)。
对于double-precision,您会得到15到17位有效十进制数字。
答案 2 :(得分:0)
其他答案都是正确的,所以我不会在这里重复。
我想补充的另一个潜在的惊喜是将==视为等价关系,这通常意味着相关性:
(a == b) and (b == c) => (a == c)
但是,如果您在https://repl.it中尝试此代码段:
class Main {
public static void main(String[] args) {
int i=16777217;
float f=16777216.0f;
double d=16777216.0;
if(i == f) {
System.out.println("i == f");
}
if(d == f) {
System.out.println("d == f");
}
if(i == d) {
System.out.println("i == d");
}
}
}
令人惊讶的是i==f
和f==d
,但not(i==d)
...
这是因为在编写i==f
时,会发生隐式转换float(i)==f
,并且此转换可能会松散精度,因为int可能需要高达31位的精度,而float最多可提供24位。
这可能有所不同,如果你看看Lisp,Scheme或最近的Squeak / Pharo Smalltalk如何处理比较,你会发现他们关心的是准确性......
摘自http://www.lispworks.com/documentation/lcl50/aug/aug-170.html
通常,当操作涉及有理点和浮点参数时,有理数首先转换为浮点格式,然后执行操作。 此转换过程称为浮点传染。但是,对于数字相等比较,使用有理算法比较参数,以确保相等(或不等式)关系的传递性。