两个double 变量怎么比较大小?

时间:2023-01-30 18:02:28
double a = 99.0123456789123456789d;
double b = 99.0123456789123456788d;

String.valueOf(a) :99.01234567891234
14位后面的都被截取掉了,怎么判断a 都等于b

怎样才能让精确度更高能,并判断a 是否等于b ?

23 个解决方案

#1


用BigDecimal

#2


java的精确计算要用BigDecimal

#3


怎么使用啊?
double a = 99.0123456789123456789d;
BigDecimal aa = new BigDecimal(a);
这样比较还是相等啊?

#4


public static void main(String argv[]){
double a = 99.0123456789123456789d;
double b = 99.0123456789123456788d;
if(a == b){
System.out.println("a = b");
}
else {
System.out.println("a != b");
}
}
直接比。

#5


这样直接比较是相等的,实际是不相等的。精度问题

#6


不需要BigDecimal吧,直接比就可以。
因为你使用String来表示这个double的时候就会有精度损失,但是其大小是不变的

#7


double a = 99.0123456789123456789d;
精度只能到99.01234567891234。

而BigDecimal a = new BigDecimal(99.0123456789123456789d);
              99.012345678912339508315199054777622222900390625
的精度实质也到99.01234567891234。

所以:
public static void main(String argv[]){
BigDecimal a = new BigDecimal(99.0123456789123456789d);
BigDecimal b = new BigDecimal(99.0123456789123456788d);
if(String.valueOf(a).equals(String.valueOf(b))){
System.out.println("a = b");
}
else {
System.out.println("a != b");
}
System.out.println(String.valueOf(a)+"\n"+String.valueOf(b));
}
结果一样。

#8


long double a = 99.0123456789123456789d;
long double b = 99.0123456789123456788d;
在比较应该能行吧

#9


这样可的到结果:
public static void main(String argv[]){
BigDecimal a = new BigDecimal("99.0123456789123456789");
BigDecimal b = new BigDecimal("99.0123456789123456788");
if(String.valueOf(a).equals(String.valueOf(b))){
System.out.println("a = b");
}
else {
System.out.println("a != b");
}
System.out.println(String.valueOf(a)+"\n"+String.valueOf(b));
}
上几例中问题都出在99.0123456789123456789d 的到的是double型,这时就被截成了99.01234567891234。

#10


给你个笨方法,把整数和小数部分都取出来分别比较,hoho

#11


a != b
99.0123456789123456789
99.0123456789123456788

#12


问题是
double a = 99.0123456789123456789d;
double b = 99.0123456789123456788d;
的比较问题,怎样才能不损失精度,转换成BigDecimal

#13


跑这个嘛:
public static void main(String argv[]){
BigDecimal a = new BigDecimal("99.0123456789123456789");
BigDecimal b = new BigDecimal("99.0123456789123456788");
if(String.valueOf(a).equals(String.valueOf(b))){
System.out.println("a = b");
}
else {
System.out.println("a != b");
}
System.out.println(String.valueOf(a)+"\n"+String.valueOf(b));
}

output:

a != b
99.0123456789123456789
99.0123456789123456788

#14


还不就是比较 
0.0000000000000000009d;
0.0000000000000000008d;
的大小!

#15


问题就是double a=xxx;时精度已经丢了, 你再转成什么也没用了...

    比如用String构造,才可以看出
    BigDecimal a2 = new BigDecimal("99.0123456789123456789");
    BigDecimal b2 = new BigDecimal("99.0123456789123456788");
    if (a2.compareTo(b2) == 0) {
      System.out.println("equals");
    }

#16


99.0123456789123456789d 得到的是double型,这时就被截成了99.01234567891234。

#17


楼上已经有人说了,呵呵, 不过楼主给的源是double, 没办法

#18


99012345678912339508315199054777622222900390625
99012345678912339508315199054777622222900390625

以上是你的两个双精度数在BigDecimal 类中的值,可以看到他们两个是一样的,没法比较

#19


BigDecimal bA = new BigDecimal(99.0123456789123456789d);
BigDecimal bB = new BigDecimal(99.0123456789123456788d);
System.out.println("bA=" + bA);
System.out.println("bB=" + bB);
输出如下:
bA=99.012345678912339508315199054777622222900390625
bB=99.012345678912339508315199054777622222900390625
其实在99.0123456789123456789d转化成bA之前,99.0123456789123456789d先转成了99.01234567891234,所以其实执行的是BigDecimal bA = new BigDecimal(99.01234567891234);
BigDecimal bB = new BigDecimal(99.01234567891234);
当然bA还是与bB相等

附:JAVADOC
public BigDecimal(double val)Translates a double into a BigDecimal. The scale of the BigDecimal is the smallest value such that (10scale * val) is an integer. 
Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances notwithstanding. 

The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one. 


#20


所以正确的方法:
BigDecimal bA = new BigDecimal("99.0123456789123456789");
BigDecimal bB = new BigDecimal("99.0123456789123456788");
System.out.println("bA=" + bA);
System.out.println("bB=" + bB);
int i = bA.compareTo(bB);
System.out.println(i);
输出如下:
bA=99.0123456789123456789
bB=99.0123456789123456788
1

#21


agree

#22


问题就是double a=xxx;时精度已经丢了, 你再转成什么也没用了...

在做成double 型的时候就是99.01234567891234,

再怎么改都没有用了,所以楼主刚开始就不可以说成是double型的,

而是开始就是BigDecimal型的

#23


尽量不要用DOUBLE来比较大小

#1


用BigDecimal

#2


java的精确计算要用BigDecimal

#3


怎么使用啊?
double a = 99.0123456789123456789d;
BigDecimal aa = new BigDecimal(a);
这样比较还是相等啊?

#4


public static void main(String argv[]){
double a = 99.0123456789123456789d;
double b = 99.0123456789123456788d;
if(a == b){
System.out.println("a = b");
}
else {
System.out.println("a != b");
}
}
直接比。

#5


这样直接比较是相等的,实际是不相等的。精度问题

#6


不需要BigDecimal吧,直接比就可以。
因为你使用String来表示这个double的时候就会有精度损失,但是其大小是不变的

#7


double a = 99.0123456789123456789d;
精度只能到99.01234567891234。

而BigDecimal a = new BigDecimal(99.0123456789123456789d);
              99.012345678912339508315199054777622222900390625
的精度实质也到99.01234567891234。

所以:
public static void main(String argv[]){
BigDecimal a = new BigDecimal(99.0123456789123456789d);
BigDecimal b = new BigDecimal(99.0123456789123456788d);
if(String.valueOf(a).equals(String.valueOf(b))){
System.out.println("a = b");
}
else {
System.out.println("a != b");
}
System.out.println(String.valueOf(a)+"\n"+String.valueOf(b));
}
结果一样。

#8


long double a = 99.0123456789123456789d;
long double b = 99.0123456789123456788d;
在比较应该能行吧

#9


这样可的到结果:
public static void main(String argv[]){
BigDecimal a = new BigDecimal("99.0123456789123456789");
BigDecimal b = new BigDecimal("99.0123456789123456788");
if(String.valueOf(a).equals(String.valueOf(b))){
System.out.println("a = b");
}
else {
System.out.println("a != b");
}
System.out.println(String.valueOf(a)+"\n"+String.valueOf(b));
}
上几例中问题都出在99.0123456789123456789d 的到的是double型,这时就被截成了99.01234567891234。

#10


给你个笨方法,把整数和小数部分都取出来分别比较,hoho

#11


a != b
99.0123456789123456789
99.0123456789123456788

#12


问题是
double a = 99.0123456789123456789d;
double b = 99.0123456789123456788d;
的比较问题,怎样才能不损失精度,转换成BigDecimal

#13


跑这个嘛:
public static void main(String argv[]){
BigDecimal a = new BigDecimal("99.0123456789123456789");
BigDecimal b = new BigDecimal("99.0123456789123456788");
if(String.valueOf(a).equals(String.valueOf(b))){
System.out.println("a = b");
}
else {
System.out.println("a != b");
}
System.out.println(String.valueOf(a)+"\n"+String.valueOf(b));
}

output:

a != b
99.0123456789123456789
99.0123456789123456788

#14


还不就是比较 
0.0000000000000000009d;
0.0000000000000000008d;
的大小!

#15


问题就是double a=xxx;时精度已经丢了, 你再转成什么也没用了...

    比如用String构造,才可以看出
    BigDecimal a2 = new BigDecimal("99.0123456789123456789");
    BigDecimal b2 = new BigDecimal("99.0123456789123456788");
    if (a2.compareTo(b2) == 0) {
      System.out.println("equals");
    }

#16


99.0123456789123456789d 得到的是double型,这时就被截成了99.01234567891234。

#17


楼上已经有人说了,呵呵, 不过楼主给的源是double, 没办法

#18


99012345678912339508315199054777622222900390625
99012345678912339508315199054777622222900390625

以上是你的两个双精度数在BigDecimal 类中的值,可以看到他们两个是一样的,没法比较

#19


BigDecimal bA = new BigDecimal(99.0123456789123456789d);
BigDecimal bB = new BigDecimal(99.0123456789123456788d);
System.out.println("bA=" + bA);
System.out.println("bB=" + bB);
输出如下:
bA=99.012345678912339508315199054777622222900390625
bB=99.012345678912339508315199054777622222900390625
其实在99.0123456789123456789d转化成bA之前,99.0123456789123456789d先转成了99.01234567891234,所以其实执行的是BigDecimal bA = new BigDecimal(99.01234567891234);
BigDecimal bB = new BigDecimal(99.01234567891234);
当然bA还是与bB相等

附:JAVADOC
public BigDecimal(double val)Translates a double into a BigDecimal. The scale of the BigDecimal is the smallest value such that (10scale * val) is an integer. 
Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances notwithstanding. 

The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one. 


#20


所以正确的方法:
BigDecimal bA = new BigDecimal("99.0123456789123456789");
BigDecimal bB = new BigDecimal("99.0123456789123456788");
System.out.println("bA=" + bA);
System.out.println("bB=" + bB);
int i = bA.compareTo(bB);
System.out.println(i);
输出如下:
bA=99.0123456789123456789
bB=99.0123456789123456788
1

#21


agree

#22


问题就是double a=xxx;时精度已经丢了, 你再转成什么也没用了...

在做成double 型的时候就是99.01234567891234,

再怎么改都没有用了,所以楼主刚开始就不可以说成是double型的,

而是开始就是BigDecimal型的

#23


尽量不要用DOUBLE来比较大小