我有兴趣拥有以下getNumberOfDecimalPlace
功能:
System.out.println("0 = " + Utils.getNumberOfDecimalPlace(0)); // 0
System.out.println("1.0 = " + Utils.getNumberOfDecimalPlace(1.0)); // 0
System.out.println("1.01 = " + Utils.getNumberOfDecimalPlace(1.01)); // 2
System.out.println("1.012 = " + Utils.getNumberOfDecimalPlace(1.012)); // 3
System.out.println("0.01 = " + Utils.getNumberOfDecimalPlace(0.01)); // 2
System.out.println("0.012 = " + Utils.getNumberOfDecimalPlace(0.012)); // 3
我是否可以通过getNumberOfDecimalPlace
?
BigDecimal
以下代码无法按预期工作:
public static int getNumberOfDecimalPlace(double value) {
final BigDecimal bigDecimal = new BigDecimal("" + value);
final String s = bigDecimal.toPlainString();
System.out.println(s);
final int index = s.indexOf('.');
if (index < 0) {
return 0;
}
return s.length() - 1 - index;
}
以下内容打印出来:
0.0
0 = 1
1.0
1.0 = 1
1.01
1.01 = 2
1.012
1.012 = 3
0.01
0.01 = 2
0.012
0.012 = 3
然而,对于案例0,1.0,它不能很好地工作。我期待,结果是“0”。但结果却是“0.0”和“1.0”。这将返回“1”。
答案 0 :(得分:32)
此代码:
int getNumberOfDecimalPlaces(BigDecimal bigDecimal) {
String string = bigDecimal.stripTrailingZeros().toPlainString();
int index = string.indexOf(".");
return index < 0 ? 0 : string.length() - index - 1;
}
...通过了这些测试:
assertThat(getNumberOfDecimalPlaces(new BigDecimal("0.001")), equalTo(3));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("0.01")), equalTo(2));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("0.1")), equalTo(1));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("1.000")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("1.00")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("1.0")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("1")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("10")), equalTo(0));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("10.1")), equalTo(1));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("10.01")), equalTo(2));
assertThat(getNumberOfDecimalPlaces(new BigDecimal("10.001")), equalTo(3));
......如果那确实是你想要的。其他回复都是正确的,你必须一直使用BigDecimal而不是double / float。
答案 1 :(得分:29)
结合Turismo,Robert和user1777653's答案,我们得到了:
int getNumberOfDecimalPlaces(BigDecimal bigDecimal) {
return Math.max(0, bigDecimal.stripTrailingZeros().scale());
}
1.0
有0位小数)。scale()
比String.indexOf()
更有效。scale()
表示零小数位。你有它,两全其美。
答案 2 :(得分:3)
这不是你的代码错了,而是你的期望。 double
基于二进制浮点表示,完全不适合精确表示小数部分。十进制0.1例如当以二进制表示时,它具有无限数量的数字,因此它被截断,当转换回十进制时,你得到最低有效数字的错误。
如果您独占使用BigDecimal
,您的代码将按预期运行。
答案 3 :(得分:3)
如果你真的得到双打,我建议在创建BigDecimal
之前先将它们格式化为字符串。至少那对我有用:How to check if a double has at most n decimal places?
根据您期望的位数,您可以使用标准格式化
String.valueOf(doubleValue);
或者您可以使用专门的格式来避免指数格式
DecimalFormat decimalFormat = new DecimalFormat();
decimalFormat.setMaximumIntegerDigits(Integer.MAX_VALUE);
// don't use grouping for numeric-type cells
decimalFormat.setGroupingUsed(false);
decimalFormat.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US));
value = decimalFormat.format(numericValue);
如果您有BigDecimal
,只需拨打scale()
即可获得小数位数。
答案 4 :(得分:2)
试试这个:
Math.floor(Math.log(x) / Math.log(10))
0.001 = -3
0.01 = -2
0.1 = -1
1 = 0
10 = 1
100 = 2
答案 5 :(得分:2)
应该这样做
int getNumberOfDecimalPlace(BigDecimal number) {
int scale = number.stripTrailingZeros().scale();
return scale > 0 ? scale : 0;
}
答案 6 :(得分:2)
无需转换为String,直接使用比例应该更有效:
private int getNumberOfDecimalPlaces(BigDecimal bigDecimal)
{
int scale = bigDecimal.stripTrailingZeros().scale();
return scale>0?scale:0;
}
答案 7 :(得分:0)
如何看看BigDecimal的javadoc。我不确定,但我会试试getScale和getPercision。
答案 8 :(得分:0)
获取具有指定小数位数的BigDecimal的最佳方法是使用setscale方法。我个人也喜欢使用该方法的舍入版本(见下面的链接):
http://java.sun.com/j2se/1.5.0/docs/api/java/math/BigDecimal.html#setScale(int,%20int)
如果您想要获取BigDecimal当前设置的小数位数,请调用相关的scale()方法。
答案 9 :(得分:0)
到目前为止我找到的最佳选项(不需要toString + index):
analysis.include
答案 10 :(得分:-1)
提供代码示例:
System.out.println("0 = " + BigDecimalUtil.getNumberOfDecimalPlace("0")); // 0
System.out.println("1.0 = " + BigDecimalUtil.getNumberOfDecimalPlace("1.0")); // 0
System.out.println("1.01 = " + BigDecimalUtil.getNumberOfDecimalPlace(new BigDecimal("1.01"))); // 2
System.out.println("1.012 = " + BigDecimalUtil.getNumberOfDecimalPlace(new BigDecimal("1.012"))); // 3
System.out.println("0.01 = " + BigDecimalUtil.getNumberOfDecimalPlace("0.01")); // 2
System.out.println("0.012 = " + BigDecimalUtil.getNumberOfDecimalPlace("0.012")); // 3
System.out.println("0.00000000000000000012 = " + BigDecimalUtil.getNumberOfDecimalPlace("0.00000000000000000012")); // 20
getNumberOfDecimalPlace的重载版本,因此您可以将它与BigDecimal或String一起使用:
public static int getNumberOfDecimalPlace(String value) {
final int index = value.indexOf('.');
if (index < 0) {
return 0;
}
return value.length() - 1 - index;
}
public static int getNumberOfDecimalPlace(BigDecimal value) {
return getNumberOfDecimalPlace(value.toPlainString());
}
答案 11 :(得分:-6)
为什么不直接更改代码以获得双倍小数位?
public static int getNumberOfDecimalPlace(double value) {
//For whole numbers like 0
if (Math.round(value) == value) return 0;
final String s = Double.toString(value);
System.out.println(s);
final int index = s.indexOf('.');
if (index < 0) {
return 0;
}
return s.length() - 1 - index;
}