How to fix the number of numeric characters in a float?

Asked

Viewed 5,300 times

4

I wrote a simple code where at the end of a precise mathematical operation the result would be seven numeric characters regardless of where the point is. Unfortunately I can only adjust the precision of the decimals but I need something like this: 10.0000 or 1000.01 or 0.00007 the "size" of the number needs to always be truncated with 7 characters. For example, for the result: -3.1700000000419095 0.0 0.0 precise adjust to: -3.1700 0.00000 0.00000

  • 3

    What if the result requires more than 7 characters, such as 10,000,000? Is it impossible to obtain such a value in the operations done? And as questioned in the questions, the point and the negative sign should count within this limit of 7? Because you specify seven numeric characters, but in the example you only put 5, because there is the point and minus sign.

4 answers

2

TL;DR

You can do this by calculating the size of the unit part, whether it is negative or not, and then round up the number according to the previous numbers.

def num_to_7_char(num):
    if num == 0:
        return "0.00000"

    int_part = int(log10(abs(num))) + 1
    minus_part = int(num < 0)
    round_to = max(6 - int_part - minus_part, 0)

    return "{num:.{round_to}f}".format(num=num, round_to=round_to)

Code working on Repl.it

Explanation

If the number is zero, returns 0.00000 because a logarithm of 0 cannot be calculated.

To calculate the unit part of the number I use the method math.log10 to know how many houses the number has, calculating how many times I have to multiply the number 10 to reach the desired number. Ex.:

from math import log10

print(log10(1))    # 0
print(log10(10))   # 1
print(log10(100))  # 2

I use the method abs to take the module of a number, because to calculate a logarithm the number must be greater than 0.

Utilise int to convert the result to an integer and sum 1 so that the calculation corresponds to the number of unit digits of the number.

To calculate the space that will be occupied by the character - (minus sign) I do a simple conversion from Boolean to integer, where True will become 1 and False will become 0.

The variable round_to stores the amount we want in the decimal places, as this will depend on how many characters will be left of the point.

The calculation of the rounding is done by decreasing the whole part and the part of the signal of the desired total. In this case the total desired is 6, because it is necessary to consider that the point will occupy a character.

The max is being used so that the case of round_to be negative, it sets minimum limit to zero. Ex.:

max(1, 0)  # 1
max(0, 0)  # 0
max(-1, 0) # 0

In the end it is used string formatting using the method str.format to round up and limit the number. The site Pyformat has good examples to understand how it works.


Note that this model does not work properly in some cases for obvious reasons certain numbers are not possible to be represented in 7 characters without specifying some other rules, for example:

  • Number greater than 9_999_999: because it would take at least 8 characters to represent them.
  • 6-digit integers: The algorithm uses the rule to convert a int for float and fill the remaining characters with zeros to the right, but if an integer has only 6 digits it is not possible to represent it because only one point could be added, without being able to add zeros.

1

Use the basics: "{0:.number of decimal placesf}". format(number)

>>>"{0:.2f}".format(1/7)
>>>'0,14'
>>>
>>>"{0:.5f}".format(1/2)
>>>'0.50000'

0

def trunca_sete(num):
    return '%.7s' % (str(num).ljust(7, '0'))

trunca_sete(-3.1700000000419095)
'-3.1700'
trunca_sete(0.0)
'0.00000'
trunca_sete(1000.01)
'1000.01'
trunca_sete(1000.0199999)
'1000.01'

0

Turn it into a string and then cut it out. If the number is smaller than the size you want, fill in with zeros on the left:

def numero_sete(numero):
    numero = float(numero)
    numero = str(numero)
    numero = numero[:7]
    numero = numero.ljust(7, '0')

    return numero

numero_sete(-3.1700000000419095)
'-3.1700'
numero_sete(0.01)
'0.01000'
  • If you do numero_sete(1) returns 1000000 instead of 1.00000, then it is interesting to ensure that the value treated is float, making str(float(numero))

  • Really. Since all of his examples were float, I thought this was a requirement

  • And an alternative to ljust is to use one’s own format, but I believe it doesn’t make much difference: '{0:0<7}'.format(str(float(test))[:7])

Browser other questions tagged

You are not signed in. Login or sign up in order to post.