【发布时间】:2012-11-20 20:39:21
【问题描述】:
我正在编写一个简单的方法来计算十进制值的小数位数。该方法如下所示:
public int GetDecimalPlaces(decimal decimalNumber) {
try {
int decimalPlaces = 1;
double powers = 10.0;
if (decimalNumber > 0.0m) {
while (((double)decimalNumber * powers) % 1 != 0.0) {
powers *= 10.0;
++decimalPlaces;
}
}
return decimalPlaces;
我已经针对一些测试值运行了它,以确保一切正常,但在最后一个值上又出现了一些非常奇怪的行为:
int test = GetDecimalPlaces(0.1m);
int test2 = GetDecimalPlaces(0.01m);
int test3 = GetDecimalPlaces(0.001m);
int test4 = GetDecimalPlaces(0.0000000001m);
int test5 = GetDecimalPlaces(0.00000000010000000001m);
int test6 = GetDecimalPlaces(0.0000000001000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001m);
测试 1-5 工作正常,但 test6 返回 23。我知道传入的值超过了最大十进制精度,但为什么是 23?我发现奇怪的另一件事是,当我在来自 test6 的调用之后在 GetDecimalPlaces 方法中放置一个断点时,该方法中的 decimalNumber 的值与来自 test5 的值(20 个小数位)相同,但即使该值传入有20位小数返回23。
也许只是因为我传入的数字有太多小数位并且事情变得不稳定,但我想确保我没有遗漏一些根本错误的东西,这可能会导致其他值的计算失败稍后在路上。
【问题讨论】:
-
只是一个猜测,但我知道如果运行代码的硬件支持它,或者它可以在编译时执行计算,该语言保留使用比它所说的更精确的权利在将其存储在变量中之前的时间文字;给出的精度是最小值,而不是精确值。
-
出于好奇,只是转换为字符串并计算小数点后的字符不是更快更容易吗?我知道像 23.23e3 这样的数字存在一些问题,但应该不难适应。
-
@TimSchmelter 哈哈哈谢谢你让我的一天很有趣
-
@TyCobb 我最初是使用 string.Split('.') 和计数来实现的,但是在不使用'.'的不同 CultureInfo 中会出现问题。作为它的小数分隔符,然后您必须开始对字符串进行各种杂乱无章的工作,以确保值仍然是好的。这更加精确,并确保我们只处理数值而不是字符串