验证是否在没有任何精度损失的情况下创建了大小数

Validate if big decimal is created without any precision loss

我有一个接受 BigDecimal 的方法。我想确保它的十进制值没有精度损失(即)大十进制的输入完全按原样存储。我的理解是当我尝试将无限双精度转换为大十进制时会发生精度损失,因此建议使用双精度的字符串表示形式创建大十进制。基本上,我想确定是否使用 BigDecimal(String) 为此类无限双精度构造大小数。

根据我在完成 doc 后的理解,在大十进制转换期间导致精度损失的输入双精度值总是非常大,不适合 64 位。示例:0.1。因此,如此大的小数的字符串和双精度值表示将不匹配。当字符串和双精度值不匹配时,是否足以说发生了精度损失?
例如:
BigDecimal 小数 = new BigDecimal(0.1);
System.out.println(decimal.toString()) // 打印 0.1000000000000000055511151231257827021181583404541015625
System.out.println(decimal.doubleValue()) // 打印 0.1.
big decimal 的 string 和 double 值不同,因此发生精度损失。

如果允许 BigDecimal 作为算术结果,这个想法就会失效。

如果您要要求 BigDecimal 是十进制字符串转换的直接、未修改的结果,那么在您的方法中要求 String 参数并将其转换为 BigDecimal 会简单得多。

以下程序试图实施和测试您的有效性检查。变量 third 是在没有任何双精度参与的情况下计算的,仅使用十进制字符串和 BigDecimal,但未通过测试。

import java.math.BigDecimal;
import java.math.RoundingMode;

public strictfp class Test {
    public static void main(String[] args) {
        BigDecimal third = BigDecimal.ONE.divide(new BigDecimal("3"), 30, RoundingMode.HALF_EVEN);
        testIt(new BigDecimal("0.1"));
        testIt(new BigDecimal(0.1));
        testIt(third);
    }

    static void testIt(BigDecimal in) {
        System.out.println(in+" "+isValid(in));
    }

    static boolean isValid(BigDecimal in) {
        double d = in.doubleValue();
        String s1 = in.toString();
        String s2 = Double.toString(d);
        return s1.equals(s2);
    }
}

输出:

0.1 true
0.1000000000000000055511151231257827021181583404541015625 false
0.333333333333333333333333333333 false