双精度浮点数(Java)

时间:2021-10-07 17:11:07

Is there any in built function in java to tell me how many decimal places in a double. For example:

在java中有内置函数告诉我一个双精度浮点数是多少。例如:

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

I am happy to convert to another type first if needed, I have looked at converting to bigdecimal first with no luck.

如果需要的话,我很乐意先转换成另一种类型,我先考虑了转换成bigdecimal。

7 个解决方案

#1


8  

No.

不。

1.100 and 1.1 are exactly the same value (they are represented exactly the same bit-for-bit in a double).

1.100和1.1是完全相同的值(它们在double中表示完全相同的位对位)。

Therefore you can't ever get that kind of information from a double.

因此你不可能从替身那里得到这样的信息。

The only thing you can do is to get the minimum number of decimal digits necessary for a decimal number to be parsed into the same double value. And that is as easy as calling Double.toString() and checking how many decimal digits there are.

你能做的唯一的一件事是得到一个要被解析成相同的双值的十进制数的最小数目。这就像调用doubley . tostring()并检查有多少位小数一样简单。

#2


13  

You could use BigDecimal.scale() if you pass the number as a String like this:

您可以使用BigDecimal.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

but if you already have the number as string you might as well just parse the string with a regex to see how many digits there are:

但是如果你已经有了数字作为字符串,你也可以用regex解析字符串,看看有多少位数字:

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

Using BigDecimal might have the advantage that it checks if the string is actually a number; using the string method you have to do it yourself. Also, if you have the numbers as double you can't differentiate between 1.31 and 1.310 (they're exactly the same double) like others have pointed out as well.

使用BigDecimal可以检查字符串是否是一个数字;使用string方法,你必须自己动手。另外,如果数字是2倍,你就不能像其他人指出的那样区分1。31和1。310(它们是完全相同的2倍)。

#3


3  

No, there is no built-in function that I know about.

不,我不知道有什么内置函数。

There is a simple way to do this, though. Double.toString will give you a string containing ALL significant decimal digits in the double. The following are some properties of that string:

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

  • The String that results may be in decimal notation or scientific notation, depending on the value of the double.
  • 结果可能是十进制记数法或科学记数法,这取决于两倍的值。
  • Doubles that convert to decimals 10,000,000 or larger or smaller than 1/1000 result in scientific notation. Otherwise, they are in decimal notation.
  • 将小数转化为1000万或大于或小于1/1000的两倍结果就是科学的表示法。否则,它们是十进制的。

Using Double.toString to figure out how many decimal places there are essentially comprises how many significant digits to the right of the decimal point minus a scientific notation exponent, if there is one. Decimal notation will always have at least one digit to the right of the decimal point, and at least one digit to the left of the decimal point, even if it is a zero. Since we are concerned about decimal places for significant digits, a trailing zero to the right of the decimal point is a concern and should not be counted as a decimal place.

使用双。要算出有多少位小数,本质上包括小数点右边有多少位有效数字减去一个科学的符号指数,如果有的话。十进制记数法在小数点右至少有一位,在小数点左至少有一位,即使它是零。因为我们关心的是有效数字的小数位数,所以小数点右边的零位是一个问题,不应该被算作小数。

The following code will make a good calculation for you:

下面的代码将为您做一个很好的计算:

    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);

I have some questions about the question posed. What kind of precision is expected with the decimal representation of a double? Are doubles being used to inappropriately perform decimal computations? Decimal computations with decimal fractions using floats and doubles can have results that unexpectedly have 16 or 17 significant digits and may be only approximations of the expected results from equivalent decimal computations.

我对提出的问题有一些疑问。对于双精度的十进制表示,期望有什么样的精度?是否使用双精度来不恰当地执行十进制计算?使用浮点数和双精度数进行十进制计算的结果可能出人意料地有16或17位有效数字,并且可能仅仅是等效十进制计算的预期结果的近似。

One aspect of float, doubles, long doubles (aka quads) that seems to stymie programmers and designers is that all these formats are actually stored as binary fractional numbers that can only approximate decimal numbers except for a very, very few numbers, most of which are fairly close to the values 1, -1, plus the value zero. As one progresses towards positive infinity or zero from 1, or towards negative infinity or zero from -1, the sparseness of the approximation will become apparent.

浮动的一个方面,双打,长双打(又名四)似乎阻碍程序员和设计师是所有这些格式实际上是存储为二进制小数的数字只能近似小数除了一个,数量非常少,其中大部分是相当接近的值1,1,加上零价值。当一个人从1走向正无穷或0,或从-1走向负无穷或0,近似值的稀疏性将变得明显。

Almost all decimal fractions have no direct representation in floats and doubles. Only decimal fractions that can be comprised from the sum of some combination of the following series of fractions have an exact representation:

几乎所有的十进制分数在浮点数和双精度数中都没有直接表示。只有小数部分可以由下面一系列分数的组合的和得到一个精确的表示:

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

1、1/2、1/4,1/8,1/8,1/32,1/64,1/128,1/256,…,1/4503599627370496

All the rest are approximations.

其余的都是近似值。

Integers greater than +9007199254740992 or less than -9007199254740992 may not have an exact representation and the sparseness increases exponentially as integers increase above the positive or decrease below the negative values, respectively.

大于+9007199254740992或小于-9007199254740992的整数可能没有精确的表示,并且随着整数分别在正值上增加或在负值下减少,稀疏性呈指数增长。

Another way to look at this is to realize that IEEE 64-bit doubles, normalized, approximate positive and negative decimal numbers having absolute values ranging from 2.225073858507201400 E -308 through 1.797693134862315700 E +308. However, there are only 1.8446744073709551616 E +19 values available for these approximations. That means about 1.0 E +607 decimal values share a representation with some other decimal values that are more closely approximated by a double.

另一种理解这一点的方法是了解IEEE 64位双精度、规范化、近似正负十进制数的绝对值从2.225073858507201400 E -308到1.797693134862315700 E +308。然而,对于这些近似,只有1.8446744073709551616 E +19个值可用。这意味着大约1.0 E +607十进制值与其他一些更接近于double的小数值共享一个表示。

The behavior of floats and doubles wrecks havoc with decimal computations requiring exact decimal accuracy, such as financial calculations and is why, unless a high-precision approximation is acceptable, one should use scaled integers and longs, or classes such as BigInteger and BigDecimal, for computations requiring exact decimal accuracy, rounding and precision.

浮点数和双精度数残骸严重破坏的行为要求精确的十进制小数计算的准确性,如金融计算和为什么,除非高精度近似是可以接受的,一个人应该使用整数扩展和多头,先导入BigInteger和BigDecimal,或类等需要精确计算小数精度、舍入和精度。

#4


2  

The number of decimal places in a double is 16.

双精度浮点数是16。

64-bit numbers. 52-bit Mantissa. 52 bits is about 16 decimal digits.

64位数字。52位尾数,52位是16位小数。

See http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html.

见http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html。

double, whose values include the 64-bit IEEE 754 floating-point numbers.

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

See http://en.wikipedia.org/wiki/IEEE_754-2008

见http://en.wikipedia.org/wiki/ieee_754 - 2008

#5


2  

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

#6


0  

From many long years ago, I recall an answer of 16 digits, total of before and after the decimal point.

从很久以前,我回忆起一个16位数字的答案,总共是小数点后和之后。

I wrote a tiny bit of code to test that.

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

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

There 4+12 = 16 digits. A run outputs 3411.999999999999.

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

Now add one more 9 behind the decimal point for a total of 17 - 3411.9999999999999 - and rerun. The value printed is 3412.0. In this case, we overload the internal representation of x, and the number is rounded internally to store.

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

The println faithfully prints what it sees internally. There are only so many bits - 64 to be exact - to hold the double floating number (significand and exponent - see IEEE 754 for the gory details).

println忠实地打印它在内部看到的内容。只有如此多的位(确切地说,是64位)来保存双浮点数(表示和指数),详见IEEE 754。

Play around with the value of x and you'll see the effects. For instance, 0.9999999999999999 (16 9s)give output 0.9999999999999999; 0.99999999999999999 (17 9s) gives 1.0.

使用x的值,你会看到效果。例如,0.99999999999999999999 (16 9s)输出0.99999999999999999999999999;0.999999999999999 (179s)给出1.0。

Hope this helps.

希望这个有帮助。

#7


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

#1


8  

No.

不。

1.100 and 1.1 are exactly the same value (they are represented exactly the same bit-for-bit in a double).

1.100和1.1是完全相同的值(它们在double中表示完全相同的位对位)。

Therefore you can't ever get that kind of information from a double.

因此你不可能从替身那里得到这样的信息。

The only thing you can do is to get the minimum number of decimal digits necessary for a decimal number to be parsed into the same double value. And that is as easy as calling Double.toString() and checking how many decimal digits there are.

你能做的唯一的一件事是得到一个要被解析成相同的双值的十进制数的最小数目。这就像调用doubley . tostring()并检查有多少位小数一样简单。

#2


13  

You could use BigDecimal.scale() if you pass the number as a String like this:

您可以使用BigDecimal.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

but if you already have the number as string you might as well just parse the string with a regex to see how many digits there are:

但是如果你已经有了数字作为字符串,你也可以用regex解析字符串,看看有多少位数字:

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

Using BigDecimal might have the advantage that it checks if the string is actually a number; using the string method you have to do it yourself. Also, if you have the numbers as double you can't differentiate between 1.31 and 1.310 (they're exactly the same double) like others have pointed out as well.

使用BigDecimal可以检查字符串是否是一个数字;使用string方法,你必须自己动手。另外,如果数字是2倍,你就不能像其他人指出的那样区分1。31和1。310(它们是完全相同的2倍)。

#3


3  

No, there is no built-in function that I know about.

不,我不知道有什么内置函数。

There is a simple way to do this, though. Double.toString will give you a string containing ALL significant decimal digits in the double. The following are some properties of that string:

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

  • The String that results may be in decimal notation or scientific notation, depending on the value of the double.
  • 结果可能是十进制记数法或科学记数法,这取决于两倍的值。
  • Doubles that convert to decimals 10,000,000 or larger or smaller than 1/1000 result in scientific notation. Otherwise, they are in decimal notation.
  • 将小数转化为1000万或大于或小于1/1000的两倍结果就是科学的表示法。否则,它们是十进制的。

Using Double.toString to figure out how many decimal places there are essentially comprises how many significant digits to the right of the decimal point minus a scientific notation exponent, if there is one. Decimal notation will always have at least one digit to the right of the decimal point, and at least one digit to the left of the decimal point, even if it is a zero. Since we are concerned about decimal places for significant digits, a trailing zero to the right of the decimal point is a concern and should not be counted as a decimal place.

使用双。要算出有多少位小数,本质上包括小数点右边有多少位有效数字减去一个科学的符号指数,如果有的话。十进制记数法在小数点右至少有一位,在小数点左至少有一位,即使它是零。因为我们关心的是有效数字的小数位数,所以小数点右边的零位是一个问题,不应该被算作小数。

The following code will make a good calculation for you:

下面的代码将为您做一个很好的计算:

    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);

I have some questions about the question posed. What kind of precision is expected with the decimal representation of a double? Are doubles being used to inappropriately perform decimal computations? Decimal computations with decimal fractions using floats and doubles can have results that unexpectedly have 16 or 17 significant digits and may be only approximations of the expected results from equivalent decimal computations.

我对提出的问题有一些疑问。对于双精度的十进制表示,期望有什么样的精度?是否使用双精度来不恰当地执行十进制计算?使用浮点数和双精度数进行十进制计算的结果可能出人意料地有16或17位有效数字,并且可能仅仅是等效十进制计算的预期结果的近似。

One aspect of float, doubles, long doubles (aka quads) that seems to stymie programmers and designers is that all these formats are actually stored as binary fractional numbers that can only approximate decimal numbers except for a very, very few numbers, most of which are fairly close to the values 1, -1, plus the value zero. As one progresses towards positive infinity or zero from 1, or towards negative infinity or zero from -1, the sparseness of the approximation will become apparent.

浮动的一个方面,双打,长双打(又名四)似乎阻碍程序员和设计师是所有这些格式实际上是存储为二进制小数的数字只能近似小数除了一个,数量非常少,其中大部分是相当接近的值1,1,加上零价值。当一个人从1走向正无穷或0,或从-1走向负无穷或0,近似值的稀疏性将变得明显。

Almost all decimal fractions have no direct representation in floats and doubles. Only decimal fractions that can be comprised from the sum of some combination of the following series of fractions have an exact representation:

几乎所有的十进制分数在浮点数和双精度数中都没有直接表示。只有小数部分可以由下面一系列分数的组合的和得到一个精确的表示:

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

1、1/2、1/4,1/8,1/8,1/32,1/64,1/128,1/256,…,1/4503599627370496

All the rest are approximations.

其余的都是近似值。

Integers greater than +9007199254740992 or less than -9007199254740992 may not have an exact representation and the sparseness increases exponentially as integers increase above the positive or decrease below the negative values, respectively.

大于+9007199254740992或小于-9007199254740992的整数可能没有精确的表示,并且随着整数分别在正值上增加或在负值下减少,稀疏性呈指数增长。

Another way to look at this is to realize that IEEE 64-bit doubles, normalized, approximate positive and negative decimal numbers having absolute values ranging from 2.225073858507201400 E -308 through 1.797693134862315700 E +308. However, there are only 1.8446744073709551616 E +19 values available for these approximations. That means about 1.0 E +607 decimal values share a representation with some other decimal values that are more closely approximated by a double.

另一种理解这一点的方法是了解IEEE 64位双精度、规范化、近似正负十进制数的绝对值从2.225073858507201400 E -308到1.797693134862315700 E +308。然而,对于这些近似,只有1.8446744073709551616 E +19个值可用。这意味着大约1.0 E +607十进制值与其他一些更接近于double的小数值共享一个表示。

The behavior of floats and doubles wrecks havoc with decimal computations requiring exact decimal accuracy, such as financial calculations and is why, unless a high-precision approximation is acceptable, one should use scaled integers and longs, or classes such as BigInteger and BigDecimal, for computations requiring exact decimal accuracy, rounding and precision.

浮点数和双精度数残骸严重破坏的行为要求精确的十进制小数计算的准确性,如金融计算和为什么,除非高精度近似是可以接受的,一个人应该使用整数扩展和多头,先导入BigInteger和BigDecimal,或类等需要精确计算小数精度、舍入和精度。

#4


2  

The number of decimal places in a double is 16.

双精度浮点数是16。

64-bit numbers. 52-bit Mantissa. 52 bits is about 16 decimal digits.

64位数字。52位尾数,52位是16位小数。

See http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html.

见http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html。

double, whose values include the 64-bit IEEE 754 floating-point numbers.

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

See http://en.wikipedia.org/wiki/IEEE_754-2008

见http://en.wikipedia.org/wiki/ieee_754 - 2008

#5


2  

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

#6


0  

From many long years ago, I recall an answer of 16 digits, total of before and after the decimal point.

从很久以前,我回忆起一个16位数字的答案,总共是小数点后和之后。

I wrote a tiny bit of code to test that.

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

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

There 4+12 = 16 digits. A run outputs 3411.999999999999.

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

Now add one more 9 behind the decimal point for a total of 17 - 3411.9999999999999 - and rerun. The value printed is 3412.0. In this case, we overload the internal representation of x, and the number is rounded internally to store.

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

The println faithfully prints what it sees internally. There are only so many bits - 64 to be exact - to hold the double floating number (significand and exponent - see IEEE 754 for the gory details).

println忠实地打印它在内部看到的内容。只有如此多的位(确切地说,是64位)来保存双浮点数(表示和指数),详见IEEE 754。

Play around with the value of x and you'll see the effects. For instance, 0.9999999999999999 (16 9s)give output 0.9999999999999999; 0.99999999999999999 (17 9s) gives 1.0.

使用x的值,你会看到效果。例如,0.99999999999999999999 (16 9s)输出0.99999999999999999999999999;0.999999999999999 (179s)给出1.0。

Hope this helps.

希望这个有帮助。

#7


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