Python 3 number rounding

Asked

Viewed 1,193 times

1

I am developing a project to calculate the wear of certain parts of a vehicle. However, I am still new to the Python language.

My problem, for example, is this::

The liter of fuel costs R $ 5,83, which in turn causes my vehicle to travel 22 km. Therefore, I have an expense of R $ 0,265 per kilometer driven.

If I use the function ceil, this final amount would be rounded to R $ 1,00. Being that the interesting would be rounded to R $ 0,27.

Which function or operation is most appropriate in this case?

  • Use the round() function, search for it in the documentation.

3 answers

6

suggestion 1

a good practice in such cases, if the accuracy is not too critical is to let Python store the value of the accounts as they are made, without worrying about that value - and, just at the time of present value to users you round with the number of desired decimal places.

In doing so, if you have several operations to perform with some numbers, Python stores all intermediate results in the maximum accuracy allowed by 64-bit floating point numbers. This causes errors that could be entered in your accounts by a rounding before the time are cancelled at the end.

For the representation, what you have to keep in mind is the following: the number is in a Python variable, and at some point your program will generate the output for the end user. It doesn’t matter if this output is in an HTML snippet, if it is a web application, it is shown in a print on the terminal, it is shown in a widget on the screen, it is exported in a CSV-type file, or it is saved in a database: it is only then that the smallest accuracy matters. And in all of the above cases, and a few more, the number is serialized as a string of decimal digits. (The only exception is the database, if it is only consumed by its application proria back, can leave the number without rounding in the database as well).

Then, you can use the string formatting syntax, with the new Python 3.6 f-strings, to specify the exact number of decimal places you want, and the language rounds to you - including taking care of cases of broken numbers because they cannot be represented correctly on the binary basis - which is the native format of floating point numbers.

For example, in your case, with preco_por_literro = 5.83 km_wheelsets = 22 litros_supplied = 1 preco_por_km = preco_por_literro * litros_abastecidos / km_rodados

If you print "preco_por_km" with print(preco_por_km), arrives in the 0.265 - but if you use string formatting, you can do:

print(f"Preço por km: R${preco_por_km:.02f}")

The "f-strings" { } in a string, and, if after the expression, there is the delimiter :, apply on the result to formatting mini-language. In case we have :02f, meaning "a floating point number with two boxes after the decimal point, filled with 0 if the number is round".

suggestion 2

Another good practice - especially when dealing with financial values, is, instead of using native floating point numbers, which has limitations to represent some decimal numbers, and other rounding restrictions, to work around with decimal numbers. In Python, these are another numeric type - the class decimal.Decimal - in that case, after each number entry, and after each operation, the result is rounded to the desired number of houses - and the print will only have the desired number of houses (where the final presentation may be adjusted in the same way as the previous one, for example to include the "00" of the cents after the decimal point if the number is round).

There are two cool tips there: the first is that the standard precision of the decimals is large, so it is important to change the context to only have two decimal points. The second is that nobody wants to keep typing decimal.Decimal(1) for each time you put a number in the program, then you can use the syntax from decimal import Decimal as D to bear the name D representing the class decimal.Decimal

from decimal import Decimal as D, getcontext, setcontext
# As próximas 3 linhas limitam o contexto dos números a duas casas decimais
ctx = getcontext()
ctx.prec = 2
setcontext(ctx)

preco_por_litro = D('5.83')
km_rodados = D(22)
litros_abastecidos = D(1)
preco_por_km = preco_por_litro * litros_abastecidos / km_rodados
print(preco_por_km)

And this will print 0.26, only with two houses - only .026 instead of the 0.27 - on account of what I wrote above, by changing the context, the intermediate result of each operation is rounded to only two decimal places - then the ". 005" of the ". 265" gets lost in the path (even if you adjust the rounding extrateness of the decimal context - which is also configurable - it will only take effect if the internal representation of the numbers is greater than two decimal places), and you use the format of strings at the time of printing, as in the previous case.

extra information

Python has 3 rounding functions for floating point numbers - math.floor, math.ceil, that require the import of the module math,and the function round which is built-in (builtin). This usage, in addition to only rounding a number to the nearest integer, as happens in most other languages, allows a second parameter, optional, indicating the number of decimal places desired. You can use this round by passing "2" in the second parameter when printing your accounts' result, no string formatting, and so on - but you have to keep in mind that if you try to limit the number to two decimal places in your accounts' intermediate results, the code will be subject to the limitations that are part of how floating point numbers work (this link is the same as the second one above) - including, depending on the number, and the form of printing, it can "expand" again to more than two decimal places, even with the use of the "round". Example of use: print(round(preco_por_km), 2). The functions math.ceil and math.floor will always round to whole numbers. The numbers of the type decimal.Decimal, even if used internally with greater precision, has the method quantize which permits rounding by passing a decimal number as a parameter 1.00 (to two decimal places). Ex.: print(preco_por_km.quantize(D('1.00')) - if the context has more than two boxes will print 0.27. (remember, with the Decimal you can work with unlimited internal precision - just that operations with more than a few tens of thousands of digits will start to get really slow)

  • Thank you very much friend. Your explanation solved and very much my problem, not to mention that enriched my learning. Again thank you very much.

2

Hello, all right? I am very new in the field of programming, but, I hope to help.

Below is an example that would round the way you need it:

preço=float(input('Qual o preço do combustível: R$'))

km=float(input('Quantos quilômetros são gastos por litro: '))

total= preço/km

print('{:.2f}'.format(total))

NOTE: print('{:.2f}'.format(total)) On this command line, I put keys and format what should be shown inside them. I put .format(total)...it will show the total, however, as I put {:.2f} I say ''Show me the result with only 2 floating points', {:.2f} and it makes the rounding the way you want it. It’s 0.27

  • We are 2 hehehe. I thought about it too, but I needed to round up the number. The format is good but does not round up in these cases.

2

Uses the function round().

It receives two parameters (number to be rounded, number of decimals). In your case just put round(0.265, 2) who will return 0.27.

Beware of using , or ..

  • Thank you very much, this function ended up helping me to solve the problem.

  • If you can mark as the correct answer it would be great =D

Browser other questions tagged

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