Skip to content
Advertisement

How to disable python rounding?

I’m looking for a way to disable this:

print(0+1e-20) returns 1e-20, but print(1+1e-20) returns 1.0

I want it to return something like 1+1e-20.

I need it because of this problem:

from numpy import sqrt


def f1(x):
  return 1/((x+1)*sqrt(x))


def f2(x):
  return 1/((x+2)*sqrt(x+1))


def f3(x):
  return f2(x-1)


print(f1(1e-6))
print(f3(1e-6))
print(f1(1e-20))
print(f3(1e-20))

returns

999.9990000010001
999.998999986622
10000000000.0
main.py:10: RuntimeWarning: divide by zero encountered in double_scalars
  return 1/((x+2)*sqrt(x+1))
inf

f1 is the original function, f2 is f1 shifted by 1 to the left and f3 is f2 moved back by 1 to the right. By this logic, f1 and f3 should be equal to eachother, but this is not the case.

I know about decimal. Decimal and it doesn’t work, because decimal doesn’t support some functions including sin. If you could somehow make Decimal work for all functions, I’d like to know how.

Advertisement

Answer

As others have stated, in general this can’t be done (due to how computers commonly represent numbers).

It’s common to work with the precision you’ve got, ensuring that algorithms are numerically stable can be awkward.

In this case I’d redefine f1 to work on the logarithms of numbers, e.g.:

from numpy as sqrt, log, log1p, 

def f1(x):
    prod = log1p(x) + log(x) / 2
    return exp(-prod)

You might need to alter other parts of the code to work in log space as well depending on what you need to do. Note that most stats algorithms work with log-probabilities because it’s much more compatible with how computers represent numbers.

f3 is a bit more work due to the subtraction.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement