Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.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_Rounding - Fatal编程技术网

双精度小数位数是多少(Java)

双精度小数位数是多少(Java),java,rounding,Java,Rounding,java中有没有内置函数来告诉我一个双精度小数位数是多少。例如: 101.13 = 2 101.130 = 3 1.100 = 3 1.1 = 1 -3.2322 = 4 etc. 如果需要的话,我很乐意先转换成另一种类型,我已经考虑过先转换成bigdecimal,但运气不好。双精度的小数位数是16 64位数字。52位尾数。52位大约是16位十进制数字 看 double,其值包括64位IEEE 754浮点数 请参见编号 1.100和1.1是完全相同的值(它们在双精度中以完全相同的位表示) 因此

java中有没有内置函数来告诉我一个双精度小数位数是多少。例如:

101.13 = 2
101.130 = 3
1.100 = 3
1.1 = 1
-3.2322 = 4 etc.

如果需要的话,我很乐意先转换成另一种类型,我已经考虑过先转换成bigdecimal,但运气不好。

双精度的小数位数是16

64位数字。52位尾数。52位大约是16位十进制数字

double,其值包括64位IEEE 754浮点数

请参见编号

1.100和1.1是完全相同的值(它们在
双精度
中以完全相同的位表示)

因此,您永远无法从
double
获取此类信息


您唯一能做的就是获取将十进制数解析为相同的
double
值所需的最小十进制位数。这就像调用Double.toString()
并检查小数位数一样简单。

如果您将数字作为如下字符串传递,则可以使用bigdecim.scale()

BigDecimal a = new BigDecimal("1.31");
System.out.println(a.scale()); //prints 2
BigDecimal b = new BigDecimal("1.310");
System.out.println(b.scale()); //prints 3
但是,如果您已经将数字作为字符串,您也可以使用正则表达式解析该字符串,以查看有多少个数字:

String[] s = "1.31".split("\\.");
System.out.println(s[s.length - 1].length());

使用BigDecimal可能有一个优点,即它检查字符串是否实际上是一个数字;使用string方法,您必须自己完成。另外,如果你把数字设为双精度,你就不能像其他人指出的那样区分
1.31
1.310
(它们是完全相同的双精度)。

不,我知道没有内置函数

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

  • 结果可能是十进制或科学的字符串 表示法,取决于double的值
  • 转换为小数10000000或大于或小于 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);
我对提出的问题有一些疑问。对于double的十进制表示,需要什么样的精度?是否使用双精度不适当地执行十进制计算?使用浮点数和双精度小数的十进制计算可能会产生意外的16或17位有效数字的结果,并且可能只是等效十进制计算的预期结果的近似值

浮点、双精度、长双精度(又名四边形)似乎阻碍了程序员和设计师的一个方面是,所有这些格式实际上都存储为二进制分数,只能近似于十进制数,除了极少数数字,其中大多数非常接近值1,-1加上值0。当一个人从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.0e+607个十进制值与其他一些更接近双精度的十进制值共享一个表示形式


浮点和双精度的行为破坏了要求精确十进制精度的十进制计算,如金融计算,这就是为什么除非可以接受高精度近似值,否则应使用缩放整数和长整数,或类,如BigInteger和BigDecimal,用于要求精确十进制精度的计算,四舍五入和精度

多年前,我记得一个16位数的答案,小数点前后的总数

// ****************************************************************
public int getDecimals(double doubleValue) {
// ****************************************************************
    BigDecimal bd1 = new BigDecimal(Double.toString(doubleValue)).stripTrailingZeros();
    return bd1.scale();
}
我写了一小段代码来测试它

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.9999999

现在在小数点后再加一个9,总数为17-3411.999999999999-然后重新运行。打印的值为3412.0。在本例中,我们重载x的内部表示,并在内部对数字进行四舍五入以存储

println忠实地打印它在内部看到的内容。只有如此多的位(准确地说是64位)来保存双浮点数(有效位和指数-请参阅IEEE 754了解详细信息)

使用x的值,您将看到效果。例如,0.99999999999(16 9秒)给出的输出为0.9999999999999;0.999999999999999(17 9秒)表示1.0

呵呵
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
    }  
}