0

I've written some script to help me out finding if something is divisible by other thing, and it fails with larger numbers:

print(x, d)
90744169766518547761620274468374441720233236940 10
print(x/d)
9.074416976651854e+45
print(x / (x/d))
10.0
print(x % (x/d))
2.535301200456459e+30

Since 10.0 is clearly lacking decimal part I don't undertand why % is giving me this trash output?

Verthais
  • 300
  • 3
  • 14
  • you probably don;t know python3 changed how division operator works – Bing Wang Feb 13 '21 at 19:53
  • This is just another example how floating point operations have limited precision. – trincot Feb 13 '21 at 19:55
  • The cited duplicates do not answer this question. There are two parts: 1. Python 3 `/` rounds the inputs to the nearest floating-point numbers, and then rounds the quotient to the nearest floating-point number; if you want integer division you need to use `//`. 2. The remainder is actually computed exactly: fl() = 90744169766518546396101782568721709290584276992, fl(fl()/10) = 9074416976651854386080058211226290629717786624, and fl(fl() % fl(fl()/10)) = fl() % fl(fl()/10) = 2535301200456458802993406410752 = `2.535301200456459e+30`. – Floating Pundit Feb 14 '21 at 16:53
  • But the remainder _function_ (even if, in floating-point arithmetic, it is computed exactly) can magnify a very small error in the input into a very large error in the output, just like subtracting nearby approximations magnifies very small error in the inputs to very large errors in the outputs (catastrophic cancellation), and the logarithm function can magnify a very small error in inputs near 1 into arbitrarily large errors in the outputs (motivation for log1p). None of this part of what's going on has anything to do with floating-point—it's inherent to the nature of %, −, log. – Floating Pundit Feb 14 '21 at 16:56

1 Answers1

1

Does this do what you expect?

>>> print(x//d)
9074416976651854776162027446837444172023323694
>>> print(x // (x//d))
10
>>> print(x % (x//d))
0

The difference is that / in Python 3 always produces a floating point result, even if the operands are integers. In this it differs from C. If you want integer division you need to use //.

BoarGules
  • 16,440
  • 2
  • 27
  • 44
  • Your answere is on point, however someone closed this question linking some seemingly unrelated topics. Since I get the precission risks associated with floating points but that does not get me any closer to undestanding the problem at hand. – Verthais Feb 13 '21 at 20:31