I am somewhat perplexed by this (presumably very simple) issue.
Simply, I am trying to find the leading digit(s) in any number (related question). Here is some nice python code (from this question):
import math
def first_n_digits(num, n):
# where n is the number of leading digits of interest
return num // 10 ** (int(math.log(num, 10)) - n + 1)
This works great for most numbers, for example:
>>> first_n_digits(123456, 1)
1
>>> first_n_digits(123456, 2)
12
>>> first_n_digits(123456, 3)
123
>>> first_n_digits(123456, 4)
1234
>>> first_n_digits(123456, 5)
12345
>>> first_n_digits(123456, 6)
123456
The problem is this does not work for num=1000
and n=1
.
first_n_digits(1000, 1)
10
This issue does not appear when num = 10,100,10000,100000
. Just num = 1000
.
How can one deal with this edge case? I have not found any others so far. I expect there to be some very simple solution which I have overlooked.
Best Answer
The problem is simply rounding errors. The operation
int
when applied to a (positive?) float, rounds the number down to the nearest integer. This works fine if we pretend that the output ofmath.log
is exact, but it is not:There are ways to fix this, e.g. by testing what happens if you compute 10 to the power of the output of this computation, but the more general difficulty is that you can never guarantee that floating point operations will be exact, simply because it's impossible to represent all possible real numbers on a computer.
In fact, the Pythonic way to solve your problem is the entirely robust function (at least for positive integers, and assuming
n
takes on a reasonable value)