4

用于从服务器读取jsonJSONObject响应。服务器返回一些十进制数。普通数字是没有问题的,但是当有十进制数字时就会出现问题0.00068。像这样的数字0.00068会自动存储到Double对象中,当尝试检索此类数字时,将返回数字的“计算机科学记数法”,即 6.8E4,即使该数字通过方法以 double 形式访问getDouble(index)或通过方法以 String 形式访问getString(index)

已经尝试过这种将 double 值转换为字符串的方法,但已经消除了这种技术,因为在Double转换为BigDecimal. 这可以通过在缩放到 时舍入设置来消除BigDecimal.ROUND_CEILING。但是我不想要任何缩放并且想要原始值,因为实际值是一个小十进制数,并且服务器保证该数字不会超过小数点后的 6 位。

BigDecimal big = new BigDecimal(new Double(0.00680));

System.out.println(big.toPlainString()); //0.006799999999999999621136392846665330580435693264007568359375

System.out.println(big.setScale(15, BigDecimal.ROUND_DOWN)); //0.006799999999999

是否有某种方法可以在没有缩放的情况下获得 Double 的实际字符串值,即数字 0.00680,或者我们可以防止JSONObject将数字解释为它们各自的数字类。

提前致谢。

4

2 回答 2

5

与您使用的 JSON 库无关,您不应使用带双精度参数的BigDecimal 构造函数,因为它使用双精度二进制浮点值的精确十进制表示

相反,请使用静态valueOf方法,因为它使用 double 的字符串值,因此可以正确舍入。

当必须将 double 用作 BigDecimal 的源时,请注意此构造函数提供了精确的转换;它与使用Double.toString(double)方法将双精度转换为字符串然后使用BigDecimal(String)构造函数给出的结果不同。要获得该结果,请使用静态valueOf(double)方法。

但是,对于非常大或非常小的数字,解析为 double 可能已经引入了舍入错误,在这种情况下,唯一的解决方案是使用支持将数字解析为 BigDecimals 的不同 JSON 库。

于 2012-01-03T13:26:37.637 回答
0

在 org.json.JSONObject 类中注释掉方法 stringToValue(String string) 中的行

    /*
     * If it might be a number, try converting it. If a number cannot be
     * produced, then the value will just be a string.
     */

    char initial = string.charAt(0);
    if ((initial >= '0' && initial <= '9') || initial == '-') {
        try {
            // if we want full Big Number support this block can be replaced with:
            // return stringToNumber(string);
            if (isDecimalNotation(string)) {
                Double d = Double.valueOf(string);
                if (!d.isInfinite() && !d.isNaN()) {
                    return d;
                }
            } else {
                Long myLong = Long.valueOf(string);
                if (string.equals(myLong.toString())) {
                    if (myLong.longValue() == myLong.intValue()) {
                        return Integer.valueOf(myLong.intValue());
                    }
                    return myLong;
                }
            }
        } catch (Exception ignore) {
        }
    }
于 2018-08-09T08:03:07.017 回答