Home > front end >  Round numbers of different lengths to nearest 0 or 5
Round numbers of different lengths to nearest 0 or 5

Time:01-22

How to round numbers of different length size to the nearest zero or five?

Example:

1291 -> 1290
0.069 -> 0.07
1.08 -> 1.1
14 -> 15
6 -> 5

Tried to use round() and math.ceil() / math.floor() but since the numbers are different each time in length I can’t adapt it dynamically, numbers are returning from a function not an array.

CodePudding user response:

I wrote a code and explained. It seems working. I didn't take into account negative numbers.

import numpy as np
convDict = {
    "0":"0",
    "1":"0",
    "2":"0",
    "3":"5",
    "4":"5",
    "5":"5",
    "6":"5",
    "7":"5",
    "8":"0",
    "9":"0"
}

def conv(f):
    str_f = str(f)
    
    # if input is like, 12. or 13.0,so actually int but float data type
    # We will get rid of the .0 part
    if str_f.endswith(".0"):
        str_f = str(int(f))

    # We need last character, and other body part
    last_f = str_f[-1]
    body_f = str_f[:-1]

    # if last char is 8 or 9 we should increment body last value
    if last_f in "89":
        # Number of decimals
        numsOfDec = body_f[::-1].find('.')

        # numsOfDec = -1 means body is integer, we will add 1
        if numsOfDec == -1:
            body_f = str(int(body_f)   1)

        else:
            # We will add 10 ** -numsOfDec , but it can lead some numerical differences like 0.69999, so i rounded
            body_f = str(np.round(float(body_f)   10 ** (-numsOfDec),numsOfDec))

    # Finally we round last char
    last_f = convDict[last_f]
    return float(body_f   last_f)

And some examples,

print(conv(1291))
print(conv(0.069))
print(conv(1.08))
print(conv(14))
print(conv(6))
print(conv(12.121213))
print(conv(12.3))
print(conv(18.))
print(conv(18))

CodePudding user response:

Here you are, thanks for the other solutions:

import math
import decimal

def round_half_up(n):
    if (str(n).find(".") > 0):
        decimalsource = len(str(n).split(".")[1])
        base = 10**decimalsource
        number = n*base
        rounded = 5 * round(number/5)
        result = rounded / base
        if (result == int(result)):
            return int(result)
        else:
            return result
    else:
        return 5 * round(n/5)

      
print(round_half_up(1291))
print(round_half_up(0.069))
print(round_half_up(1.08))
print(round_half_up(14))
print(round_half_up(6))
print(round_half_up(12.121213))
print(round_half_up(12.3))
print(round_half_up(18.))
print(round_half_up(18))

CodePudding user response:

The kinda pythonic way to round dynamically to nearest five would be to use round() function and input number (divided by 5), the index in which you want the rounding to ocurr [-2: hundreds, -1: tens, 0: whole, 1:1/10ths, 2:1/100s] and multiply result by 5. You can calculate this index by finding how many decimal places there are using decimal module.

 i = decimal.Decimal('0.069')
 i.as_tuple().exponent
 -3 

Note that this function takes the number as a string and outputs the number of decimal places in negative.

After getting this number, make it positive, and there you have the calculated index to put into the round function in the beginning.

round(0.069/5, 3) * 5

You need to also check before all this calculation if the number is a full number (meaning no decimal places--17, 290, 34.0) (in that case you shouldn't use above code at all), which you can easily do by using modulus, so the overall function would look like this:

 if number % 1 == 0:
     return round(int(number)/5)*5
 else:
     index = decimal.Decimal(str(number)).as_tuple().exponent
     return round(number/5, -index)*5

Hope this helped !

  • Related