I want to round down a float to a specific number of significant digits. Very similar to this answer: https://stackoverflow.com/a/3411435/281021 but instead of the normal round()
behavior, it should round down always. I can't use math.floor()
because it turns the float into an int.
Basically, 0.45
should become 0.4
instead of 0.5
.
And 1945.01
should become 1000.0
instead of 2000.0
.
Scientific representation seems to be the way to go, but numerical techniques usually end up faster for me than string techniques. You do get the occasional floating point error however...
from math import *
def roundDown(x, sigfigs=1): #towards -inf
exponent = floor(log10(copysign(x,1))) #we don't want to accidentally try and get an imaginary log (it won't work anyway)
mantissa = x/10**exponent #get full precision mantissa
# change floor here to ceil or round to round up or to zero
mantissa = floor(mantissa * 10**(sigfigs-1)) / 10**(sigfigs-1) #round mantissa to sigfigs
return mantissa * 10**exponent
Rounding towards zero or +inf is as easy as changing the floor
to ceil
or round
. Another benefit of computing the mantissa and exponent numerically rather than casting to a string is that the number of sigfigs can be easily changed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With