Jump to content

Divisão e arredondamento causado pelas formatação do print


jonhhy
Go to solution Solved by pwseo,

Recommended Posts

Viva

try: # (tenta)
  a = int(input('Numerador: '))
  b = int(input('Denominador: '))
  r = a / b
except: 
  print('Infelizmente tivemos um problema :(')
else:
  print(f'O resultado é {r}')
  print(f'Resultado 1 casa decimal é {r:.1f}')
  
Numerador: 5
Denominador: 4
O resultado é 1.25
Resultado 1 casa decimal é 1.2

Numerador: 5
Denominador: 3
O resultado é 1.6666666666666667
Resultado 1 casa decimal é 1.7

Resultado 5/4
Resultado 5/3

Porque num arredonda para cima e no outro para baixo?  

Quais são os critérios usados?

Link to comment
Share on other sites

  • 2 months later...
  • Solution

@jonhhy

Em Python, o arredondamento segue as regras definidas no IEEE-754, e portanto o comportamento é arredondar na direcção do dígito menos significativo par quando o valor se situa a meio da escala. Exemplos:
 

>>> def f(val):
...     print(f'{val:.1f}')
...
>>> [ f(x) for x in [1.1, 1.25, 1.35, 1.67] ]
1.1
1.2
1.4
1.7

Se reparares bem, o arredondamento de 1.25 e 1.35 vai em direcções opostas, precisamente pela regra que enunciei acima: no caso de 1.25, o dígito menos significativo par mais próximo é 2 (pois 3 é ímpar) e portanto arredonda-se na direcção do 2, para 1.2. Já no caso de 1.35, o dígito menos significativo par mais próximo é 4 (novamente, porque 3 é par) e portanto arredonda-se na direcção do 4, para 1.4. No caso do 1.67 a dúvida não se coloca, porque o último dígito não está a meio da escala (ie. o número não termina num dígito decimal 5), e portanto arredonda-se na direcção dígito menos significativo inteiro mais próximo, que neste caso é 7, para 1.7.

Espero ter ajudado.

  • Vote 2
Link to comment
Share on other sites

  • 2 months later...
Em 07/03/2023 às 15:52, passarito disse:

Boas,

@pwseo, isso é tudo muito bonito e claro que não coloco em questão o que dizes, antes pelo contrário, mas como é que se pode meter o Python a fazer os arredondamentos ditos normais?

Obrigado

Dependerá o que se pretende com os arredondamentos. Se não importar a precisão exata do arredondamento, pode utilizar a função round, e nos parâmetros passa o número a arredondar e o número de casas decimais que pretende.

print(round(valor, 2))

Agora se precisa de precisão extrema nos cálculos tem de usar uma biblioteca chamada Decimal.

from decimal import Decimal

soma = Decimal('0.1') + Decimal('0.1') + Decimal('0.1')
print(soma)

 

Edited by Cerzedelo
  • Vote 1
Link to comment
Share on other sites

O Python que estou a usar é o do software da maquina de calcular da TEXAS ti-nspire cx e se eu colocar print(round(8.7,2)) retorna o valor 8.699999999999999

Simplesmente estúpido, nem retorna o valor que lhe dei, nem respeita o round

Já se eu em vez de usar o valor 8.7 , usar o valor 8.6 funciona na bem.

Sei que foge um pouco ao tópico, mas não sei até que ponto estará relacionado.

Link to comment
Share on other sites

Em 08/03/2023 às 14:44, passarito disse:

(...)

Simplesmente estúpido, nem retorna o valor que lhe dei, nem respeita o round

(...)

Sei que foge um pouco ao tópico, mas não sei até que ponto estará relacionado.

Diria que estás a deparar-te com o facto de que nem todos os números decimais são perfeitamente representáveis em binário. Repara que a função round() devolve um número (e não uma string), e por isso se o resultado não for representável em binário, obterás uma apenas o número representável mais próximo. O @Cerzedelo exemplificou como utilizar o Decimal para ultrapassar essas limitações (embora, logicamente, com alguma perda de performance).

No módulo Decimal existem também opções para especificar que estratégia de arredondamento utilizar, embora nunca tenha tido necessidade de as utilizar.

Link to comment
Share on other sites

Este problema do arredondamento não é exclusivo do python, estende-se a outras linguagens de programação. Simplificando tem a ver como o python (pelo menos nas versões mais modernas) interpreta os números, através do sistema de 64 bits. E nesse sistema por exemplo ao efetuar uma soma de dois números, a representação binário desse número será de 64 caracteres e esse soma não é inteiramente igual à soma que fazemos no sistema decimal, será muito próxima.

Por exemplo se em python somar 0.1+0.1+0.1 o resultado será 0.30000000000000004 e não 0.3 como se usa no sistema decimal, por isso é que depois se executa os arredondamentos.

Por isso como referi, se não tiver importância a exatidão do arredondamento, utiliza-se a função round(), se se pretende uma exatidão precisa utiliza-se a biblioteca Decimal, que olha para os números da soma como strings e  não como números.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.