时间:2010-07-26 10:57:30

标签: java rounding

7 个答案:

答案 0 :(得分:14)

答案 1 :(得分:8)

答案 2 :(得分:3)

答案 3 :(得分:3)

不,我没有内置的功能。

但有一种简单的方法可以做到这一点。 Double.toString将为您提供一个包含double中所有有效十进制数字的字符串。以下是该字符串的一些属性:

  • 结果的字符串可以是十进制表示法或科学字符 符号,取决于double的值。
  • 转换为10,000,000或更大或小于的小数的双打 1/1000导致科学记数法。否则,它们是十进制的 符号

使用Double.toString计算出小数点右边有多少位小数除了科学记数指数(如果有的话)。十进制表示法始终在小数点右侧至少有一位数字,小数点左侧至少有一位数,即使它是零。由于我们关注有效位的小数位,因此小数点右侧的尾随零是一个问题,不应计为小数位。

以下代码将为您做好计算:

    StringBuffer stringBuffer = new StringBuffer(Double.toString(1234.567890D));
    System.out.println(stringBuffer.toString());
    int i; // general purpose character index
    int exponent;
    int decimalPlaces;
    if ((i = stringBuffer.indexOf("E")) > -1) { // scientific notation...
        // turn scientific notation exponent into an integer
        exponent = Integer.parseInt(stringBuffer.substring(i + 1));
        // truncate the exponent from the StringBuffer
        stringBuffer = stringBuffer.delete(i, stringBuffer.length());
    } else { // decimal notation, could be trailing zero
        exponent = 0; // no exponent, so zero
        // point i to trailing zero and truncate it, if there is one
        if (stringBuffer.charAt((i = stringBuffer.length() - 1)) == '0') {
            stringBuffer = stringBuffer.deleteCharAt(i); // delete trailing zero
        }
    }
    // stringBuffer now contains only significant digits to the
    // right of the decimal point, if there are any
    decimalPlaces = stringBuffer.length() - 1 - stringBuffer.indexOf(".") - exponent;
    // zero or positive number is decimal places
    // negative number is number of zeroes to the left of the decimal point
    // between the decimal point and the least significant digit
    System.out.println(decimalPlaces);

我对提出的问题有些疑问。双精度的十进制表示期望什么样的精度?双打被用于不恰当地执行十进制计算吗?使用浮点数和双精度数的十进制小数的十进制计算可能会有意外地具有16或17位有效数字的结果,并且可能只是等效十进制计算的预期结果的近似值。

浮动,双打,长双打(又称四边形)的一个方面似乎阻碍了程序员和设计师,所有这些格式实际上都存储为二进制小数,只能接近十进制数,除非是极少数,其中大多数都非常接近值1,-1,加上零值。当一个从1向正向无穷大或零向前进,或从-1向零负向或从零向进展时,近似的稀疏性将变得明显。

几乎所有小数部分都没有直接表示浮点数和双精度数。只有小数部分可以由以下一系列分数的某些组合的总和组成,具有精确的表示:

1,1 / 2,1 / 4,1 / 8,1 / 16,1 / 32,1 / 64,1 / 128,1 / 256,...,1/4503599627370496

所有其余的都是近似值。

大于+9007199254740992或小于-9007199254740992的整数可能没有精确的表示,并且稀疏度指数增加,因为整数分别高于正值或低于负值。

另一种看待这种情况的方法是认识到IEEE 64位加倍,归一化,近似正和负十进制数,其绝对值范围从2.225073858507201400 E -308到1.797693134862315700 E +308。但是,这些近似值只有1.8446744073709551616 E +19值。这意味着大约1.0 E +607十进制值与一些其他十进制值共享一个表示,这些十进制值更接近于双精度值。

浮点数和双打残骸的行为破坏了需要精确十进制精度的十进制计算,例如财务计算,这就是为什么除非高精度近似是可接受的,否则应该使用缩放的整数和长整数,或类似BigInteger和BigDecimal,用于需要精确小数精度,舍入和精度的计算。

答案 4 :(得分:2)

// ****************************************************************
public int getDecimals(double doubleValue) {
// ****************************************************************
    BigDecimal bd1 = new BigDecimal(Double.toString(doubleValue)).stripTrailingZeros();
    return bd1.scale();
}

答案 5 :(得分:0)

从很多年前,我回想起16位数的答案,小数点前后的总和。

我写了一小段代码来测试它。

public class test {
    public static void main(String[] args) {
        double x;`enter code here`
        x = 3411.999999999999;
        System.out.println("16: "+x);   // gives 3411.999999999999
        x = 3411.9999999999999;
        System.out.println("17: "+x);   // gives 3412.0
        x = 0.9999999999999999;
        System.out.println("16: "+x);   // gives 0.9999999999999999
        x = 0.99999999999999999;
        System.out.println("17: "+x);   // gives 1.0
    }  
}

有4 + 12 = 16位数。运行输出3411.999999999999。

现在在小数点后面再添加一个9,总共17 - 3411.9999999999999 - 然后重新运行。打印的值是3412.0。在这种情况下,我们重载x的内部表示,并在内部对数字进行舍入以存储。

println忠实地打印出内部看到的内容。只有这么多位 - 确切地说是64位 - 来保存双浮点数(有效数和指数 - 参见IEEE 754的血腥细节)。

玩x的值,你会看到效果。例如,0.9999999999999999(16 9s)给出输出0.9999999999999999; 0.99999999999999999(17 9s)给出1.0。

希望这有帮助。

答案 6 :(得分:-1)

StringBuffer stringBuffer = new StringBuffer(Double.toString(ratioGrossYield));
int i; // general purpose character index
int exponent;
int decimalPlaces;
if ((i = stringBuffer.indexOf("E")) > -1) { // scientific notation...
    // turn scientific notation exponent into an integer
    exponent = Integer.parseInt(stringBuffer.substring(i + 1));
    // truncate the exponent from the StringBuffer
    stringBuffer = stringBuffer.delete(i, stringBuffer.length());
} else { // decimal notation, could be trailing zero
    exponent = 0; // no exponent, so zero
    // point i to trailing zero and truncate it, if there is one
    if (stringBuffer.charAt((i = stringBuffer.length() - 1)) == '0') {
        stringBuffer = stringBuffer.deleteCharAt(i); // delete trailing zero
    }
}
// stringBuffer now contains only significant digits to the
// right of the decimal point, if there are any
decimalPlaces = stringBuffer.length() - 1 - stringBuffer.indexOf(".") - exponent;
// zero or positive number is decimal places
// negative number is number of zeroes to the left of the decimal point
// between the decimal point and the least significant digit
if (stringBuffer.charAt(stringBuffer.length() - 1) == '0') {

    return decimalPlaces-1;

} else {

    return decimalPlaces;
}