Search code examples
pythonfloating-point

Python - How to round down a float to 1 significant digit


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.


Solution

  • 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