A Double(Java)中的小数位数

在java中是否有任何内置函数告诉我double中有多少小数位。 例如:

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

如果需要,我很乐意首先转换为另一种类型,我已经考虑过转换为bigdecimal而没有运气。

没有。

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

因此,你不可能从double获得那种信息。

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

如果将数字作为字符串传递,可以使用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 

但是如果您已将数字作为字符串,那么您可以使用正则表达式解析字符串以查看有多少位数:

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

使用BigDecimal可能有一个好处,它检查字符串是否实际上是一个数字; 使用字符串方法,你必须自己做。 此外,如果您将数字设为双倍,则无法区分1.311.310 (它们完全相同),就像其他人指出的那样。

不,我没有内置的function。

但是,有一种简单的方法可以做到这一点。 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十进制值共享一个表示,其中一些其他十进制值更接近于double。

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

double中的小数位数是16。

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

请参阅http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html 。

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

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

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

从很多年前,我回想起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。

希望这可以帮助。

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