Python/maths/number_of_digits.py
Christian Clauss 6aaf0a2c77
maths/number_of_digits.py: Streamline benchmarks (#7913)
* maths/number_of_digits.py: Streamline benchmarks

```
num_digits(262144): 6 -- 0.2226011250168085 seconds
num_digits_fast(262144): 6 -- 0.13145116699161008 seconds
num_digits_faster(262144): 6 -- 0.09273383300751448 seconds

num_digits(1125899906842624): 16 -- 0.6056742920191027 seconds
num_digits_fast(1125899906842624): 16 -- 0.15698366600554436 seconds
num_digits_faster(1125899906842624): 16 -- 0.1027024170034565 seconds

num_digits(1267650600228229401496703205376): 31 -- 1.1957934170495719 seconds
num_digits_fast(1267650600228229401496703205376): 31 -- 0.15552304196171463 seconds
num_digits_faster(1267650600228229401496703205376): 31 -- 0.13062308297958225 seconds
```

* updating DIRECTORY.md

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update number_of_digits.py

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-08 11:49:47 +00:00

90 lines
1.8 KiB
Python

import math
from timeit import timeit
def num_digits(n: int) -> int:
"""
Find the number of digits in a number.
>>> num_digits(12345)
5
>>> num_digits(123)
3
>>> num_digits(0)
1
>>> num_digits(-1)
1
>>> num_digits(-123456)
6
"""
digits = 0
n = abs(n)
while True:
n = n // 10
digits += 1
if n == 0:
break
return digits
def num_digits_fast(n: int) -> int:
"""
Find the number of digits in a number.
abs() is used as logarithm for negative numbers is not defined.
>>> num_digits_fast(12345)
5
>>> num_digits_fast(123)
3
>>> num_digits_fast(0)
1
>>> num_digits_fast(-1)
1
>>> num_digits_fast(-123456)
6
"""
return 1 if n == 0 else math.floor(math.log(abs(n), 10) + 1)
def num_digits_faster(n: int) -> int:
"""
Find the number of digits in a number.
abs() is used for negative numbers
>>> num_digits_faster(12345)
5
>>> num_digits_faster(123)
3
>>> num_digits_faster(0)
1
>>> num_digits_faster(-1)
1
>>> num_digits_faster(-123456)
6
"""
return len(str(abs(n)))
def benchmark() -> None:
"""
Benchmark multiple functions, with three different length int values.
"""
from collections.abc import Callable
def benchmark_a_function(func: Callable, value: int) -> None:
call = f"{func.__name__}({value})"
timing = timeit(f"__main__.{call}", setup="import __main__")
print(f"{call}: {func(value)} -- {timing} seconds")
for value in (262144, 1125899906842624, 1267650600228229401496703205376):
for func in (num_digits, num_digits_fast, num_digits_faster):
benchmark_a_function(func, value)
print()
if __name__ == "__main__":
import doctest
doctest.testmod()
benchmark()