当前位置: 首页 > 面试题库 >

如何检查双精度数最多是否具有n个小数位?

廉博赡
2023-03-14
问题内容

目前我有这种方法:

static boolean checkDecimalPlaces(double d, int decimalPlaces){
    if (d==0) return true;

    double multiplier = Math.pow(10, decimalPlaces); 
    double check  =  d * multiplier;
    check = Math.round(check);      
    check = check/multiplier; 
    return (d==check);      
}

但是此方法失败的checkDecmialPlaces(649632196443.4279, 4)原因可能是因为我在2的基础上进行了10的数学计算。

那么如何才能正确完成此检查?

我想到了获取double值的字符串表示形式,然后使用正则表达式进行检查-但这感觉很奇怪。

编辑: 感谢所有的答案。在某些情况下,我确实获得了双倍奖励,对于这些情况,我实现了以下目标:

private static boolean checkDecimalPlaces(double d, int decimalPlaces) {
    if (d == 0) return true;

    final double epsilon = Math.pow(10.0, ((decimalPlaces + 1) * -1));

    double multiplier = Math.pow(10, decimalPlaces);
    double check = d * multiplier;
    long checkLong = (long) Math.abs(check);
    check = checkLong / multiplier;

    double e = Math.abs(d - check);
    return e < epsilon;
}

我将其更改round为截断。似乎计算完成会round大大增加不准确性。至少在失败的测试用例中。
正如你们中的一些人指出的,如果我可以进入“真实的”字符串输入,我应该使用它BigDecimal进行检查,所以我做了:

BigDecimal decimal = new BigDecimal(value);
BigDecimal checkDecimal = decimal.movePointRight(decimalPlaces);
return checkDecimal.scale() == 0;

double我获得的价值来自读取Excel文件的Apache POI
API。我进行了一些测试,发现尽管API返回double了数字单元格的值,但是当我立即doubleDecimalFormat:格式化时,我可以得到准确的表示:

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

这也适用于无法完全以二进制格式表示的值。


问题答案:

测试失败,因为您已经达到了二进制浮点表示的精度,在IEEE754 double
precision的
情况下大约为16位。将649632196443.4279乘以10000将截断二进制表示形式,从而在随后舍入和除法时导致错误,从而使函数的结果完全无效。

有关更多详细信息,请参见http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

更好的方法是检查n+1小数位是否低于某个阈值。如果d - round(d)小于epsilon(请参阅limit),则的小数表示形式d没有有效的小数位。同样,如果(d - round(d)) * 10^n小于epsilon,则d最多可以有n重要位置。

使用Jon Skeet)的代码DoubleConverter来检查d是否不够精确,无法容纳您要查找的小数位。



 类似资料:
  • 问题内容: 我有一个必须在用户界面上显示的双精度值。现在的条件是double的十进制值= 0,例如。-14.0在这种情况下,我必须仅在UI上显示14。另外,此处字符的最大限制为5。 例如:-12.34整数值不能大于2位,所以double的十进制值也不能大于2位。 最好的方法是什么? 问题答案: 你可以做 检查是否整体。

  • 问题内容: 我想使用双精度最多2个小数位。即,它将最多存储2个小数位,如果比较两个双精度值,则比较应仅基于前2个小数位。如何实现这样的事情?我的意思是存储,比较所有内容都将仅基于小数点后两位。其余位置可能不同,大于,小于,无所谓。 编辑 我的价值观不大。说从0到5000最大值。但是我必须乘以Cos A,Sin A很多次,其中A的值在程序过程中不断变化。 编辑 在我的程序中,汽车以特定速度(例如12

  • 问题内容: 我有一些这样的代码: 我基本上希望将来避免除以零的异常。 谢谢 问题答案: 如果未显式初始化,则类范围内的数字基元将初始化为零。 必须显式初始化局部范围内的数字基元(方法中的变量)。 如果您只担心被零例外除,那么检查双精度数是否不 完全 为零非常有用。 否则, 当检查浮点值是否为或时为0时,将使用错误阈值来检测该值是否接近0,但不 完全为 0。

  • 问题内容: 是否有可能做到这一点? 我知道代码可能不会去这样的事情,但怎么也去了? 问题答案: 这将检查双精度值的四舍五入值是否与双精度值相同。 你的变量可能具有或值,并且始终具有int值,因此,如果你的变量等于,则它必须具有int值。 如果变量的值是无穷大或负无穷大,那么这也不起作用,因此向条件添加“只要变量不是无穷大”。

  • 问题内容: 比较两个浮点值以实现完全相等的一种优雅,易读且不冗长的方法是什么? 听起来很简单,但这是一个严重的问题。该运营商没有得到楠所做的工作,也有特殊待遇的零: 但我想,以确定是否两个值是完全一样的(但我 不 关心不同的NaN模式,所以任何的NaN ==任何其他男- >真)。 我 可以 使用这段丑陋的Monster代码 来 做到这一点: 有没有更好的方法来编写此代码(并使意图显而易见)? 问题

  • 我试图根据浏览器的最小高度和最小宽度在我的页面上更改CSS,所以我使用这个: 但出于某种原因,这不起作用。我可以检查“最小高度”和“最大宽度”(反之亦然),或者同时检查“最大高度”和“最大宽度”,但检查“最小高度”和“最大宽度”似乎都不起作用。 我应该详细说明这一点:我希望浏览器在最小高度或最小宽度变为真时起作用。仅当两个条件均为真时,使用and运算符才有效。 我做错什么了吗?