6

遇到一些代码,其中通过将数字转换为字符串然后使用 len() 来确定位数。

Function numOfDigits_len(n As Long) As Long
    numOfDigits_len = Len(Str(n)) - 1
End Function

现在虽然这可行,但我知道与任何不使用字符串的方法相比它都会很慢,所以我写了一个使用 log() 的方法。

Function numOfDigits_log(n As Long) As Long
    numOfDigits_log = Int(Log(n) / Log(10)) + 1
End Function

将运行时间缩短了 1/2,这很棒,但在特定情况下发生了一些奇怪的事情。

  n     numOfDigits_log(n)
=====  ====================
 999            3
1000            3
1001            4

它不会1000正确处理。我认为这是因为浮点和舍入问题。

Function numOfDigits_loop(ByVal n As Long) As Long
    Do Until n = 0
        n = n \ 10
        numOfDigits_loop = numOfDigits_loop + 1
    Loop
End Function

当数字大于 10^6 时,写这个结果会慢约 10%,并且随着 n 变大,似乎会慢慢变大。如果我是务实的,那很好,但我想找到更理想的东西。

现在我的问题是,有没有办法准确地使用 log() 方法。我可以做类似的事情

Function numOfDigits_log(n As Long) As Long
    numOfDigits_log = Int(Log(n) / Log(10) + 0.000000001) + 1
End Function

但它似乎很“hacky”。有没有比 log() 方法更快或更快的更好方法?注意:我意识到这种优化在很多情况下是没有意义的,但现在我遇到了这个我想“修复”它

4

3 回答 3

1

while 循环保证正确性,即它不使用任何浮点计算

int numDigits = 0;
while(num != 0) {
    num /= 10;
    numDigits++;
}

您还可以通过使用更大的除数来加快速度

int numDigits = 0;
if(num >= 100000 || num <= -100000) {
    int prevNum;
    while(num != 0) {
        prevNum = num;
        num /= 100000;
        numDigits += 5;
    }
    num = prevNum;
    numDigits -= 5;
}
while(num != 0) {
    num /= 10;
    numDigits++;
}
于 2013-06-19T20:30:19.303 回答
1

我之前已经回答过这个问题,但我找不到它,所以这里是基础知识:

int i = ... some number >= 0 ...
int n = 1;
if (i >= 100000000){i /= 100000000; n += 8;}
if (i >= 10000){i /= 10000; n += 4;}
if (i >= 100){i /= 100; n += 2;}
if (i >= 10){i /= 10; n += 1;}

那是在 C 中,但你明白了。

于 2013-06-19T20:56:17.103 回答
0

你会喜欢这个的。

我们生活在一个以 10 为底的数字系统中!这意味着您所要做的就是ROUND UP。

一些数字的长度总是 = ceiling (log n)。例如:7456412(一个 7 位数字)。Log (7456412) = 6.8...四舍五入,你有 7. log (9999) = 3.9999。四舍五入是4。

特殊情况是当你不必四舍五入时,或者当你有一些 10 的幂时。例如:log(1000) = 3。如果你能检测到你什么时候有 10 的幂,则在 log 结果中加一你赢了!

您可以进行此检测的方式类似于

double log10;
int clog10;
int length;

log10 = (Log(n) / Log(10)); // can also use a private static final long hardcoded for Log(10)
clog10 = ceiling(log10);
if (Int(log10) == clog10)
  length = clog10 + 1;
else
  length = clog10;
于 2013-06-19T20:25:44.620 回答