Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 大十进制加错值_Java_Bigdecimal - Fatal编程技术网

Java 大十进制加错值

Java 大十进制加错值,java,bigdecimal,Java,Bigdecimal,我有一个BigDecimal定义如下: private static final BigDecimal sd = new BigDecimal(0.7d); 如果我打印它,我会得到以下值: 0.6999999999999999555910790149937383830547332763671875 这导致了一些错误的计算。有人知道如何将0.7的精确值作为BigDecimal?将其更改为0.71将查看正确的结果,但不应是这样的使用字符串文字: private static final BigD

我有一个
BigDecimal
定义如下:

private static final BigDecimal sd = new BigDecimal(0.7d);
如果我打印它,我会得到以下值:

0.6999999999999999555910790149937383830547332763671875
这导致了一些错误的计算。有人知道如何将
0.7
的精确值作为
BigDecimal
?将其更改为
0.71
将查看正确的结果,但不应是这样的

使用字符串文字:

private static final BigDecimal sd = new BigDecimal("0.7");
如果使用双精度,则实际调用。没有得到0.7的原因是它不能用
double
精确表示。有关详细信息,请参阅链接的JavaDoc。

使用字符串文字:

private static final BigDecimal sd = new BigDecimal("0.7");

如果使用双精度,则实际调用。没有得到0.7的原因是它不能用
double
精确表示。有关更多信息,请参阅链接的JavaDoc。

您应该使用声明的字符串文本值,例如
new BigDecimal(“0.7”)

您应该使用声明的字符串文本值,例如
新的BigDecimal(“0.7”)

以下是三种方法:

private static final BigDecimal sd = new BigDecimal("0.7");
private static final BigDecimal sd = new BigDecimal(0.7d, MathContext.DECIMAL32);
private static final BigDecimal sd = new BigDecimal(0.7d, MathContext.DECIMAL64)
这里有三种方法:

private static final BigDecimal sd = new BigDecimal("0.7");
private static final BigDecimal sd = new BigDecimal(0.7d, MathContext.DECIMAL32);
private static final BigDecimal sd = new BigDecimal(0.7d, MathContext.DECIMAL64)

如果您费心阅读文档,即您正在使用的javadoc,您可能已经知道答案了

  • 当必须将
    double
    用作
    BigDecimal
    的源时,请注意此构造函数提供了精确的转换;它不会给出与使用方法然后使用构造函数将
    双精度
    转换为
    字符串
    相同的结果。要获得该结果,请使用
    static
    方法
  • 然后,当您查看的javadoc时,您会发现:

    注意:这通常是将
    double
    (或
    float
    )转换为
    BigDecimal
    的首选方法,因为返回的值等于从使用的结果构造
    BigDecimal
    得到的值


    这就是你的答案:使用
    BigDecimal.valueOf(0.7d)
    ,而不是
    新的BigDecimal(0.7d)

    也许如果你费心阅读文档,即你正在使用的javadoc,你已经知道答案了

  • 当必须将
    double
    用作
    BigDecimal
    的源时,请注意此构造函数提供了精确的转换;它不会给出与使用方法然后使用构造函数将
    双精度
    转换为
    字符串
    相同的结果。要获得该结果,请使用
    static
    方法
  • 然后,当您查看的javadoc时,您会发现:

    注意:这通常是将
    double
    (或
    float
    )转换为
    BigDecimal
    的首选方法,因为返回的值等于从使用的结果构造
    BigDecimal
    得到的值


    所以这就是你的答案:使用
    BigDecimal。valueOf(0.7d)
    ,而不是
    新的BigDecimal(0.7d)

    双精度
    构造一个
    BigDecimal
    非常复杂。首先,它只能通过字符串的迂回来完成。(使用
    double
    MathContext
    的构造函数是不可能正确的。我已经尝试了很多。最新的情况是,小数点前的位数由于四舍五入而需要更改,这变得很困难。因此Javadoc中警告您不应该使用它。)

    但是,即使在那里,仅使用简单的
    String.format()
    也是不够的,因为
    String.format()
    对默认的
    Locale
    敏感,并根据系统/VM设置输出不同的十进制分隔符,而
    BigDecimal
    构造函数总是需要一个点作为十进制分隔符。因此,您必须使用
    Locale.US
    构建自己的
    格式化程序。如果您已启动并运行此功能,则会收到未关闭资源的警告

    我发现这是可行的:

    static BigDecimal toBigDecimal(double value, int decimalPlaces) {
        String format = "%." + decimalPlaces + "f";
        try (Formatter formatter = new Formatter(Locale.US)) {
            String formatted = formatter.format(format, value).toString();
            return new BigDecimal(formatted);
        }
    }
    

    double
    构造
    BigDecimal
    非常复杂。首先,它只能通过字符串的迂回来完成。(使用
    double
    MathContext
    的构造函数是不可能正确的。我已经尝试了很多。最新的情况是,小数点前的位数由于四舍五入而需要更改,这变得很困难。因此Javadoc中警告您不应该使用它。)

    但是,即使在那里,仅使用简单的
    String.format()
    也是不够的,因为
    String.format()
    对默认的
    Locale
    敏感,并根据系统/VM设置输出不同的十进制分隔符,而
    BigDecimal
    构造函数总是需要一个点作为十进制分隔符。因此,您必须使用
    Locale.US
    构建自己的
    格式化程序。如果您已启动并运行此功能,则会收到未关闭资源的警告

    我发现这是可行的:

    static BigDecimal toBigDecimal(double value, int decimalPlaces) {
        String format = "%." + decimalPlaces + "f";
        try (Formatter formatter = new Formatter(Locale.US)) {
            String formatted = formatter.format(format, value).toString();
            return new BigDecimal(formatted);
        }
    }
    

    使用
    双精度
    检查构造函数逻辑,您将了解此转换之间的困难;)感谢所有的答案,但我真的不明白为什么转换失败。我想如果位数超过精度,我只会用双精度得到错误的值。0.7应为0.7,且
    double d=0.7d;浮动f=新浮动(0.7);系统输出打印ln(f);系统输出打印ln(d)在两种情况下都精确打印0.7。
    双d=0.7d
    不要简单地存储像
    int=0
    dec=7
    这样的值,而是使用使用使用指数的尾数逻辑,反向逻辑用于创建
    BigDecimal
    。在这种情况下,从源代码到double的转换是不精确的,浮点值精度会丢失。从(不精确的)double到BigDecimal的转换是精确的。@XtremeBaumer:很明显,您不完全理解像
    double