Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python round a float to nearest 0.05 or to multiple of another float

I want to emulate this function. I want to round a floating point number down to the nearest multiple of 0.05 (or generally to the nearest multiple of anything).

I want this:

>>> round_nearest(1.29, 0.05)
1.25

>>> round_nearest(1.30, 0.05)
1.30

I can do this:

import math

def round_nearest(n, r):
    return n - math.fmod(n, r)

>>> round_nearest(1.27, 0.05)
1.25  # Correct!

>>> round_nearest(1.30, 0.05)
1.25  # Incorrect! Correct would be 1.30.

The incorrect answer above is presumably due to floating point rounding. I could put some special case check to see if the n is "close enough" to a multiple of r and not do the subtraction, and that would probably work, but is there a better way? Or is this strategy the best option?

like image 206
Andrew Magee Avatar asked Feb 10 '15 06:02

Andrew Magee


2 Answers

You can round down to the nearest multiple of a like this:

def round_down(x, a):
    return math.floor(x / a) * a

You can round to the nearest multiple of a like this:

def round_nearest(x, a):
    return round(x / a) * a
like image 113
Paul Hankin Avatar answered Sep 19 '22 12:09

Paul Hankin


As Paul wrote:

You can round to the nearest multiple of a like this:

def round_nearest(x, a):
    return round(x / a) * a

Works nearly perfectly, but round_nearest(1.39, 0.05) gives 1.4000000000000001. To avoid it I'll recommend to do:

import math

def round_nearest2(x, a):
    return round(round(x / a) * a, -int(math.floor(math.log10(a))))

Which rounds to precision a, and then to number of significant digits, that has your precision a

like image 41
Grysik Avatar answered Sep 18 '22 12:09

Grysik