Double 中有多少个小数位(Java)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3334168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How many decimal Places in A Double (Java)
提问by Karl
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,但没有运气。
采纳答案by Joachim Sauer
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 是完全相同的值(它们在 a 中逐位表示完全相同double
)。
Therefore you can't ever get that kind of information from a double
.
因此,您永远无法从double
.
The only thing you cando 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.
你唯一可以做的是让小数的最小号码数字必要被解析到相同的十进制数double
的值。这就像调用Double.toString()
和检查有多少个十进制数字一样简单。
回答by S.Lott
The number of decimal places in a double is 16.
double 中的小数位数是 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 浮点数。
回答by Andrei Fierbinteanu
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:
但是,如果您已经将数字作为字符串,那么您也可以使用正则表达式解析字符串以查看有多少位数字:
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 可能有一个好处,它会检查字符串是否实际上是一个数字;使用字符串方法你必须自己做。此外,如果您将数字设为双倍,您也无法像其他人指出的那样区分1.31
和1.310
(它们完全相同)。
回答by Jim
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:
不过,有一种简单的方法可以做到这一点。Double.toString 将为您提供一个字符串,其中包含 double 中所有有效的十进制数字。以下是该字符串的一些属性:
- 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.
- 结果的字符串可能是十进制记数法或科学记数法,具体取决于双精度值。
- 转换为 10,000,000 或大于或小于 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.
使用 Double.toString 计算出有多少小数位本质上包括小数点右侧有多少有效数字减去科学记数法指数(如果有)。十进制表示法总是在小数点右侧至少有一位数字,在小数点左侧至少有一位数字,即使它是零也是如此。由于我们关心有效数字的小数位,因此小数点右侧的尾随零是一个问题,不应算作小数位。
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.
我对提出的问题有一些疑问。double 的十进制表示期望什么样的精度?双打是否被用于不恰当地执行十进制计算?使用浮点数和双精度数进行十进制小数计算的结果可能有 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 向正无穷大或零前进,或从 -1 向负无穷大或零前进,近似的稀疏性将变得明显。
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/16, 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 十进制值与其他一些更接近于双精度值的十进制值共享一种表示形式。
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 之类的类需要精确小数精度、四舍五入和精度的计算。
回答by Erik W
// ****************************************************************
public int getDecimals(double doubleValue) {
// ****************************************************************
BigDecimal bd1 = new BigDecimal(Double.toString(doubleValue)).stripTrailingZeros();
return bd1.scale();
}
回答by Sushil
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;
}
回答by user2448902
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.9999999999999 - 然后重新运行。打印的值为 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.9999999999999999 (16 9s) 给出输出 0.9999999999999999;0.99999999999999999 (17 9s) 给出 1.0。
Hope this helps.
希望这可以帮助。