Java: BigDecimal and Double.NaN

15

我正在尝试执行以下代码:

import java.math.*;

public class HelloWorld{

     public static void main(String []args){
            System.out.println(BigDecimal.valueOf(Double.NaN));
     }
}

合理地说,我得到:

Exception in thread "main" java.lang.NumberFormatException                                                    
    at java.math.BigDecimal.<init>(BigDecimal.java:470)                                                   
    at java.math.BigDecimal.<init>(BigDecimal.java:739)                                                   
    at java.math.BigDecimal.valueOf(BigDecimal.java:1069)                                                 
    at HelloWorld.main(HelloWorld.java:6)    

在BigDecimal中有没有一种表示Double.NaN的方法?

5个回答

17
有没有办法用BigDecimal表示Double.NaN?
不行。BigDecimal类没有提供NaN、+∞或-∞的表示方法。
您可以考虑使用 null … 不过,为了表示NaN、+∞或-∞,至少需要1三个不同的值,而这是通过null不可能实现的。
您可以考虑创建一个处理这些“特殊”值的BigDecimal子类。
您可以考虑将“数字”实现为BigDecimal的包装器,并将NaN等视为特殊情况;例如:
public class MyNumber {
    private BigDecimal value;
    private boolean isNaN;
    ...

    private MyNumber(BigDecimal value, boolean isNaN) {
        this.value = value;
        this.isNaN = isNan;
    }

    public MyNumber multiply(MyNumber other) {
        if (this.isNaN || other.isNaN) {
            return new MyNumber(null, true);
        } else {
            return new MyNumber(this.value.multiply(other.value), false);
        }
    }

    // etcetera
}

上述仅为示例,我会以不同的方式实现它。


1 - IEEE 754规范还定义了正负浮点零值和多个 NaN 值。使用 Float.floatToRawIntBitsDouble.doubleToRawLongBits 方法可以区分它们。


4
"NaN"代表“不是数字”。如果浮点运算的某些输入参数导致操作产生未定义的结果,则会产生NaN。例如,0.0除以0.0在算术上未定义。对负数取平方根也是未定义的。 BigDecimal.valueOf(Double.NaN)试图将Double.NaN转换为BigDecimal,结果是无法将数字转换为BigDecimal,即java.lang.NumberFormatException


2

NaN代表不是一个数。它不是一个数字,因此无法转换为BigDecimal。


4
BigDecimal是一个对象。也许你只有它为空(null)? - Amr
合理的建议。 - Denis Kulagin
3
"Reasonable suggestion" ... 直到你考虑Double.NEGATIVE_INFINITY和Double.POSITIVE_INFINITY - Stephen C

1
您可以像这样重新编写您的代码:

 public static void main(String []args){
     Double d = ...;
     String value; 

     if (Double.isNaN(d) ==  true) {
         value= "My-NaN-formatting";
     } else {
         value=BigDecimal.valueOf(d);
     }

     System.out.println(value);
 }

2
如果你使用 BigDecimal.valueOf(d),那么你可以继续使用 double 类型。 - Axel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接