MaximumPain
MaximumPain

Reputation: 53

Modulus with decimals

I am struggling to understand the modulus part of this code.

I am trying to ONLY print the num when the modulus is 0, that is to say it's an even number. If I set number as 100 and rate as 1.5 I'll get results. However, if I change the rate value to anything other than .25 .5 .75 I get nothing returned.

Here's an example: If I use 100 as the number and 1.4 as the rate I should get 7.14.21 etc returned as 1.4 goes into these numbers evenly. However, it doesn't output.

Initial searches tells me modulus won't work for decimals yet it does for .5 increments.

Any input greatly appreciated.

def findnum(number, rate): 
    for num in range(pinumber):
        if num %(rate) == 0:
            if num != 0:                 
                print(num)

Upvotes: 0

Views: 1763

Answers (3)

bb1
bb1

Reputation: 7863

Operations on floating point numbers are not exact. For this reason 7 % 1.4 will not give precisely 0, but a number close to 0. If you replace in your code num % rate == 0 with something like num % rate < tolerance where tolerance is a small positive number (say, tolerance = 10**(-10)), it should work in most cases. However, this will still bring incorrect results for some values (try e.g. num = 5 and rate = 5/3) because Python may overestimate the value of num/rate, and then num % rate will be calculated as close to rate and not to 0. So, a safer solution is to use a condition such as abs(num/rate - round(num/rate)) < tolerance.

Upvotes: 0

CoffeeSyntax
CoffeeSyntax

Reputation: 79

Due to decimal precision in python, 7 % 1.4 doesn't give 0 precisely.

So, one approach would be using the 'isclose' function in the standard Math library to compensate for decimal precision.

if isclose(num % rate, abs_tol=1e-9):
    ...

Or, you may use the Decimal library, which offers much better precision, but requires a string conversion.

Upvotes: 0

Bertik23
Bertik23

Reputation: 469

When deviding with decimal numbers, there is always the problem of precision errors. That means, that 7 % 1.4 isn't 0 but 4.440892098500626e-16, for your code to work you must use the decimal module whitch stores the numbers as strings.

from decimal import Decimal
def findnum(number, rate): 
    for num in range(number):
        if num % Decimal(str(rate)) == 0:
            if num != 0:                 
                print(num)

Upvotes: 2

Related Questions