Melhorando a precisão de valores flutuantes em python[RESOLVIDO]

1. Melhorando a precisão de valores flutuantes em python[RESOLVIDO]

César
dark777

(usa Debian)

Enviado em 24/11/2024 - 21:20h

Boa noite galera beleza?

Ha ums tempos atras fiz algumas continhas para enter como calcular e encontrar os lados de um triangulo retângulo porem depois de um tempo tirando a prova real do triangulo pitagorico, resolvi fazer um porgrama para calcular a quantidade de metros quadrados de uma area e calcular as dimensoes e proporção da mesma, ou seja em quantas formas dá para se ter a mesma medida em metros quadrados. Entao fiz um script em python e preciso melhorar precisão dos resultados, retornados pela função ex:

Se coloco o valor de 1 ele retorna os valores flutuantes e inteiros corretamente, se coloco 100 tambem esta correto, isso daria uma área de 1 alqueire paulista até 100 alqueires paulista, mas ao utilizar por ex: 0.8 e 1.5 para calcular quantos metros quadrados teria 1.5 alqueires os resultados obtidos nao sao os mais precisos possiveis retorna muitas casas quando deveria retornar 1 ou duas casas após a virgula, entao a função esta assim:


def metrosQuadrados(*args):
if len(args) == 1:
# Calcula metros quadrados da quantidade de alqueires
resultado = (args[0] * 24200)

elif len(args) == 2:
# Calcula metros quadrados com comprimento e largura
comprimento, largura = args
resultado = (comprimento * largura)
else:
raise ValueError("Deve passar 1 ou 2 argumentos")

if isinstance(resultado, float):
return round(resultado)
else:
return round(resultado, 2)


Nesta função se eu colocar 0.8 que seria 0.8 alqueires, ou 1.5 os resultados são arredondados pela função mas na verdade estou procurando uma forma de retornar os valores corretos conforme passado para a função os resultados desfavoraveis que obtive foi este:

Dimensões área quadrada (Proporção 1:1):
Largura....: 190.53 metros
Comprimento: 190.53 metros
Hectares...: 3.63 ha.
Alqueires..: 1.4999999999999998 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 4:1):
Largura....: 95 metros
Comprimento: 381 metros
Hectares...: 3.63 ha.
Alqueires..: 1.4999999999999998 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 5:1):
Largura....: 85 metros
Comprimento: 426 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5000000000000002 alq.
Metros²....: 36300 m²


Para estas proporcoes de medidas ele retorna até que correto:

Dimensões área retângular (Proporção 1.5:1):
Largura....: 156 metros
Comprimento: 233 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 1.21:1):
Largura....: 173 metros
Comprimento: 210 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 2:1):
Largura....: 135 metros
Comprimento: 269 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 2.21:1):
Largura....: 128 metros
Comprimento: 283 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 2.42:1):
Largura....: 122 metros
Comprimento: 296 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 2.5:1):
Largura....: 120 metros
Comprimento: 301 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 3:1):
Largura....: 110 metros
Comprimento: 330 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 4.5:1):
Largura....: 90 metros
Comprimento: 404 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5 alq.
Metros²....: 36300 m²

Dimensões área retângular (Proporção 4.84:1):
Largura....: 87 metros
Comprimento: 419 metros
Hectares...: 3.63 ha.
Alqueires..: 1.5 alq.
Metros²....: 36300 m²


Bom o que esta proporção quer dizer? os valores da proporção está relacionado ao comprimento total do lado maior representando o numero de partes, desta metragem, preciso apenas corrigir o programa para funcionar com valores flutuantes, menores que 1: "0.1 ... 0.9" e "1.1 .. 1.9" , "2.1 ... 2.9" e assim por diante retornando maior precisão nos valores proporcionais passados a função "metrosQuadrados(0.1) .. metrosQuadrados(0.9), metrosQuadrados(1.1) .. metrosQuadrados(1.9) ...

Alquem poderia me dar uma luz sobre como melhorar esta função para que retorne o valor flutuante precisamente sem arredondar para cima ou para baixo retornando no maximo o numero de casas passados na função?

O programa completo é este:

import math

#########################################################################
#
# [-] Autor: Jean César Fernandes Zonta
#
# [-] DateTime: Sun Nov 24 17:28:10 2024
#
# [-] Android App: Editor de Códigos
#
# [-] Licence: GNU/GPL v2+
#
# [-] Language version: Python 3
#
# [-] Programa para calcular a o tamanho e a proporção de uma área
#
# Copyright © 2024 Todos os direitos reservados
#
#########################################################################

def metrosQuadrados(*args):
if len(args) == 1:
# Calcula metros quadrados da quantidade de alqueires
resultado = (args[0] * 24200)

elif len(args) == 2:
# Calcula metros quadrados com comprimento e largura
comprimento, largura = args
resultado = (comprimento * largura)
else:
raise ValueError("Deve passar 1 ou 2 argumentos")

if isinstance(resultado, float):
return round(resultado)
else:
return round(resultado, 2)


def calcQuadrado(area):
return math.sqrt(area)


def calcRetangulo(area, proportion=1):
largura = math.sqrt(area / proportion)
comprimento = (proportion * largura)
return largura, comprimento


def calcAlqueire(largura, comprimento):
alqueires = ((largura * comprimento) / 24200)

if isinstance(alqueires, float):
return alqueires
else:
return round(alqueires, 2)


def calcHectare(alqueire):
hectares = (alqueire * 2.42)

if isinstance(hectares, float) and hectares.is_integer():
return round(hectares)
else:
return round(hectares, 2)


def calcProportion(comprimento, largura):
proportion = (comprimento / largura)

if isinstance(proportion, float) and proportion.is_integer():
return int(proportion)
else:
return float(proportion)

def main():

# Função que transforma alqueires em metros quadrados
metros = metrosQuadrados(1.5)

# Calcula área retângular com proporção de 1:1
largura = calcQuadrado(metros)
area_quadrada = calcAlqueire(largura, largura)
proportion = calcProportion(largura, largura)
hectares = calcHectare(area_quadrada)

print(f"\nDimensões área quadrada (Proporção {proportion}:1):")
print(f"Largura....: {largura:.2f} metros")
print(f"Comprimento: {largura:.2f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_quadrada} alq.")
print(f"Metros²....: {metros} m²\n")


# Calcula área retângular com proporção de 1.5:1
largura, comprimento = calcRetangulo(metros, proportion=1.5)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 1.21:1
largura, comprimento = calcRetangulo(metros, proportion=1.21)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 2:1
largura, comprimento = calcRetangulo(metros, proportion=2)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 2.21:1
largura, comprimento = calcRetangulo(metros, proportion=2.21)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 2.42:1
largura, comprimento = calcRetangulo(metros, proportion=2.42)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 2.5:1
largura, comprimento = calcRetangulo(metros, proportion=2.5)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 3:1
largura, comprimento = calcRetangulo(metros, proportion=3)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 4:1
largura, comprimento = calcRetangulo(metros, proportion=4)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 4.5:1
largura, comprimento = calcRetangulo(metros, proportion=4.5)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 4.84:1
largura, comprimento = calcRetangulo(metros, proportion=4.84)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


# Calcula área retângular com proporção de 5:1
largura, comprimento = calcRetangulo(metros, proportion=5)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)
metros_quadrados = metrosQuadrados(comprimento, largura)

print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")

if __name__ == "__main__":
main()

wiki.anon


  


2. Re: Melhorando a precisão de valores flutuantes em python[RESOLVIDO]

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 24/11/2024 - 21:20h

Boa noite! Vamos tentar resolver o problema com a precisão dos valores flutuantes na sua função `metrosQuadrados`.

O seu código atual usa a função `round` para arredondar os resultados, mas isso pode estar causando a perda de precisão que você mencionou. Uma alternativa é limitar a quantidade de casas decimais sem arredondar os números. Para isso, podemos usar a formatação de strings ou a função `format`.

Aqui estão algumas sugestões para melhorar a sua função:

1. Remova o uso do `round` e utilize a formatação de strings para limitar as casas decimais.

2. Vamos fazer algumas modificações na sua função `metrosQuadrados` para que ela não arredonde os valores para cima ou para baixo e retorne a precisão adequada.

Abaixo está a versão atualizada da função:

```python
def metrosQuadrados(*args):
if len(args) == 1:
# Calcula metros quadrados da quantidade de alqueires
resultado = (args[0] * 24200)

elif len(args) == 2:
# Calcula metros quadrados com comprimento e largura
comprimento, largura = args
resultado = (comprimento * largura)

else:
raise ValueError("Deve passar 1 ou 2 argumentos")

# Retorna o resultado formatado com duas casas decimais sem arredondamento
return "{:.2f}".format(resultado)


3. Re: Melhorando a precisão de valores flutuantes em python[RESOLVIDO]

César
dark777

(usa Debian)

Enviado em 24/11/2024 - 21:52h


alexabolada escreveu:

Boa noite! Vamos tentar resolver o problema com a precisão dos valores flutuantes na sua função `metrosQuadrados`.

O seu código atual usa a função `round` para arredondar os resultados, mas isso pode estar causando a perda de precisão que você mencionou. Uma alternativa é limitar a quantidade de casas decimais sem arredondar os números. Para isso, podemos usar a formatação de strings ou a função `format`.

Aqui estão algumas sugestões para melhorar a sua função:

1. Remova o uso do `round` e utilize a formatação de strings para limitar as casas decimais.

2. Vamos fazer algumas modificações na sua função `metrosQuadrados` para que ela não arredonde os valores para cima ou para baixo e retorne a precisão adequada.

Abaixo está a versão atualizada da função:

```python
def metrosQuadrados(*args):
if len(args) == 1:
# Calcula metros quadrados da quantidade de alqueires
resultado = (args[0] * 24200)

elif len(args) == 2:
# Calcula metros quadrados com comprimento e largura
comprimento, largura = args
resultado = (comprimento * largura)

else:
raise ValueError("Deve passar 1 ou 2 argumentos")

# Retorna o resultado formatado com duas casas decimais sem arredondamento
return "{:.2f}".format(resultado)


não dá certo a função tem que retornar um numero decimal.

wiki.anon


4. Re: Melhorando a precisão de valores flutuantes em python[RESOLVIDO]

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 24/11/2024 - 21:52h

Olá, wiki.anon!

Entendi a sua dúvida sobre a função `metrosQuadrados`. Se você precisa que a função retorne um número decimal, ao invés de uma string formatada, você pode simplesmente retornar o resultado diretamente, sem usar a formatação de strings.

Aqui está uma versão atualizada da sua função que mantém a precisão como número decimal:

```python
def metrosQuadrados(*args):
if len(args) == 1:
# Calcula metros quadrados da quantidade de alqueires
resultado = (args[0] * 24200)

elif len(args) == 2:
# Calcula metros quadrados com comprimento e largura
comprimento, largura = args
resultado = (comprimento * largura)

else:
raise ValueError("Deve passar 1 ou 2 argumentos")

# Retorna o resultado como um número decimal
return resultado
```

Com essa modificação, agora a função retorna um número decimal sem arredondamento. Se você quiser apenas limitar a exibição desse número em outro lugar, você pode formatá-lo na hora de imprimir ou usar.

Qualquer dúvida ou se precisar de mais ajuda, é só avisar!


5. Re: Melhorando a precisão de valores flutuantes em python[RESOLVIDO]

César
dark777

(usa Debian)

Enviado em 24/11/2024 - 22:47h


alexabolada escreveu:

Olá, wiki.anon!

Entendi a sua dúvida sobre a função `metrosQuadrados`. Se você precisa que a função retorne um número decimal, ao invés de uma string formatada, você pode simplesmente retornar o resultado diretamente, sem usar a formatação de strings.

Aqui está uma versão atualizada da sua função que mantém a precisão como número decimal:

```python
def metrosQuadrados(*args):
if len(args) == 1:
# Calcula metros quadrados da quantidade de alqueires
resultado = (args[0] * 24200)

elif len(args) == 2:
# Calcula metros quadrados com comprimento e largura
comprimento, largura = args
resultado = (comprimento * largura)

else:
raise ValueError("Deve passar 1 ou 2 argumentos")

# Retorna o resultado como um número decimal
return resultado
```

Com essa modificação, agora a função retorna um número decimal sem arredondamento. Se você quiser apenas limitar a exibição desse número em outro lugar, você pode formatá-lo na hora de imprimir ou usar.

Qualquer dúvida ou se precisar de mais ajuda, é só avisar!


mas a sua sugestão volta onde o programa estava anteriormente antes da modificação, pois se retornar o valor da variavel, simplesmente ele retornará algo como:

24200.0 quando deve retornar 24200, e assim sucessivamente conforme a quantidade de metros quadrados da área.

wiki.anon


6. Re: Melhorando a precisão de valores flutuantes em python[RESOLVIDO]

Alexa Bolada
alexabolada

(usa Debian)

Enviado em 24/11/2024 - 22:47h

Olá, wiki.anon!

Entendi sua preocupação com o retorno da função `metrosQuadrados`. Para garantir que a função retorne um número inteiro ao invés de um decimal, e apenas o valor necessário sem casas decimais, você pode usar o método `int()` para converter o resultado.

Aqui está a versão atualizada da sua função:

```python
def metrosQuadrados(*args):
if len(args) == 1:
# Calcula metros quadrados da quantidade de alqueires
resultado = int(args[0] * 24200)

elif len(args) == 2:
# Calcula metros quadrados com comprimento e largura
comprimento, largura = args
resultado = int(comprimento * largura)

else:
raise ValueError("Deve passar 1 ou 2 argumentos")

# Retorna o resultado como um número inteiro
return resultado
```

Com essa modificação, a função irá retornar um número inteiro, como 24200, sem casas decimais.

Se você precisar de mais assistência ou tiver outras dúvidas, é só falar!


7. Re: Melhorando a precisão de valores flutuantes em python[AJUDA]

aguamole
aguamole

(usa KUbuntu)

Enviado em 25/11/2024 - 13:14h

Vc pode estar batendo em uma limitação computacional da atualidade e que muito provavelmente nunca poderá ser solucionada, a computação atual(computador) não consegue calcular pontos flutuantes infinitos, isso é uma limitação atual da computação.


8. Re: Melhorando a precisão de valores flutuantes em python[AJUDA]

aguamole
aguamole

(usa KUbuntu)

Enviado em 25/11/2024 - 13:40h

A calculadora "bc" ela é muito poderosa em ponto flutuante, ela consegue calcular pontos flutuante imensos.
Outra característica da calculadora BC é que ela é programável, talvez de para vc fazer toda a programação usando somente a programação interna da calculadora BC.
Para ajuda:
$ man bc 
Você também pode usar a linguagem de programação gawk uma linguagem awk muito poderosa em ponto flutuante, mas tem que ser a linguagem gawk porque existe muitas outras linguagens awk mas elas são bem mais fracas em ponto flutuante do que a gawk, a gawk perto das outras é um monstro.

https://www.gnu.org/software/gawk/
https://www.gnu.org/software/bc/

Wiki:
https://pt.wikipedia.org/wiki/Bc_(linguagem_de_programa%C3%A7%C3%A3o)

A calculadora BC por padrão ela fica configurada para fazer cálculos de ponto flutuantes pequenos, mas isso pode ser aumentado absurdamente por meio de parâmetros, leia a documentação ou vídeo no youtube caso tenha. Acho que a limitação dela esta mais é pelo quanto de RAM vc tem na sua maquina.



9. Re: Melhorando a precisão de valores flutuantes em python[AJUDA]

Buckminster
Buckminster

(usa Debian)

Enviado em 25/11/2024 - 15:08h

Faça um teste nessas partes onde não está dando como você quer (antes leia tudo):

# Calcula área retângular com proporção de 1:1
largura = calcQuadrado(metros, proportion=1.0) <<< acrescente .0
area_quadrada = calcAlqueire(largura, largura)
proportion = calcProportion(largura, largura)
hectares = calcHectare(area_quadrada)


# Calcula área retângular com proporção de 4:1
largura, comprimento = calcRetangulo(metros, proportion=4.0) <<< acrescente .0

# Calcula área retângular com proporção de 5:1
largura, comprimento = calcRetangulo(metros, proportion=5.0) <<< acrescente .0


Veja bem, nesta parte da função calcAlqueire, por exemplo:

if isinstance(alqueires, float):
return alqueires

você definiu float e está passando um inteiro em proportion.


O Python trabalha assim:

numero = 5

print(isinstance(numero, int))
# True

print(isinstance(numero, float))
# False


numero = 5.0

print(isinstance(numero, int))
# False

print(isinstance(numero, float))
# True

Talvez seja isso.
Faça um teste alterando como sugeri acima e, caso der certo, mas bagunçar em outra parte do código como

if isinstance(hectares, float) and hectares.is_integer():

basta arrumar.


Porém, caso for isso, então aqui
# Calcula área retângular com proporção de 2:1
largura, comprimento = calcRetangulo(metros, proportion=2)

e aqui
# Calcula área retângular com proporção de 3:1
largura, comprimento = calcRetangulo(metros, proportion=3)

deveria ter dado como os outros que também não tem o ponto decimal em proportion.
Dei uma olhada rápido, depois em casa dou uma olhada com mais tempo, mas quem sabe te dê uma luz por enquanto.


_________________________________________________________
Always listen the Buck!
Enquanto o cursor estiver pulsando, há vida!


10. Re: Melhorando a precisão de valores flutuantes em python[RESOLVIDO]

aguamole
aguamole

(usa KUbuntu)

Enviado em 25/11/2024 - 20:20h

Ele esta reclamando do ponto flutuante ou ele está reclamando dos valores?


11. Re: Melhorando a precisão de valores flutuantes em python[AJUDA]

César
dark777

(usa Debian)

Enviado em 26/11/2024 - 00:26h

[quote]Buckminster escreveu:

Faça um teste nessas partes onde não está dando como você quer (antes leia tudo):

# Calcula área retângular com proporção de 1:1
largura = calcQuadrado(metros, proportion=1.0) <<< acrescente .0
area_quadrada = calcAlqueire(largura, largura)
proportion = calcProportion(largura, largura)
hectares = calcHectare(area_quadrada)


# Calcula área retângular com proporção de 4:1
largura, comprimento = calcRetangulo(metros, proportion=4.0) <<< acrescente .0

# Calcula área retângular com proporção de 5:1
largura, comprimento = calcRetangulo(metros, proportion=5.0) <<< acrescente .0


Veja bem, nesta parte da função calcAlqueire, por exemplo:

if isinstance(alqueires, float):
return alqueires

você definiu float e está passando um inteiro em proportion.


O Python trabalha assim:

numero = 5

print(isinstance(numero, int))
# True

print(isinstance(numero, float))
# False


numero = 5.0

print(isinstance(numero, int))
# False

print(isinstance(numero, float))
# True

Talvez seja isso.
Faça um teste alterando como sugeri acima e, caso der certo, mas bagunçar em outra parte do código como

if isinstance(hectares, float) and hectares.is_integer():

basta arrumar.


Porém, caso for isso, então aqui
# Calcula área retângular com proporção de 2:1
largura, comprimento = calcRetangulo(metros, proportion=2)

e aqui
# Calcula área retângular com proporção de 3:1
largura, comprimento = calcRetangulo(metros, proportion=3)

deveria ter dado como os outros que também não tem o ponto decimal em proportion.
Dei uma olhada rápido, depois em casa dou uma olhada com mais tempo, mas quem sabe te dê uma luz por enquanto.

Fiz isso e funcionou até mais ou menos percebi que se preciso pegar o valor de ponto flutuante exato sem usar funções que formatam a saida ou melhoram a precisão, precisaria usar strings para pegar até duas casas decimais após a virgula, pois por python nao ser uma linguagem tipada, achei que ela poderia ter mais funçoes para tratamento de numeros decimais ou arredondamentos de ponto flutuante sem arredondar para inteiro, andei pesquisando sobre e achei uma função matematica que cria valores flutuantes, em relação a adicionar o ".0" nos números da variável proportion, poderia ser tecnicamente melhor do que em c++ que para aumentar a precisão precisa retornar um valor flutuante com duas ou mais casas decimais após a virgula... Uma coisa que nao parei para entender mas, se a função calcProportion estiver com a variavel definida com um valor seja ele "proportion=0" mesmo que passe o valor no vetor com o valor das proporções ele imprime a mesma proporção de 1:1 duas vezes? seria mesmo necessário definir um valor na variável "proportion" sem aferar os valores dos resultados finais ou evitar que imprima o mesmo resultado duas vezes?. Isso mesmo se a variavel sem haver redundancia do mesmo calculo, aliás se tratando de um programa pequeno isso nao faz diferença mas em um codigo com várias classes e estruturas de dados, garantiria um codigo mais bem escrito, dei uma analizada melhor no codigo com base nas sugestoes aqui, e cheguei a isso:

import math

#########################################################################
#
# [-] Autor: Jean César Fernandes Zonta
#
# [-] Licence: GNU/GPL v2+
#
# [-] Programing Language: Python 3
#
# [-] Android App: Editor de Códigos
#
# [-] Programa para calcular o tamanho e proporção de uma área
#
# Copyright © 2024 Todos os direitos reservados
#
#########################################################################

def metrosQuadrados(*args):
try:
if len(args) == 1:
# Calcula metros quadrados de uma área
return int(args[0] * 24200)

elif len(args) == 2:
# Calcula metros quadrados com comprimento e largura
return int(args[0] * args[1])

except ValueError:
raise ValueError("Enter 1 or 2 arguments")


def calcQuadrado(area):
try:
area = float(area)
return math.sqrt(area)

except ValueError:
raise ValueError("Instance value not a number")


def calcRetangulo(area, proportion=1.0):
try:
area = float(area)
proportion = float(proportion)

largura = math.sqrt(area / proportion)
comprimento = (proportion * largura)

return largura, comprimento

except ValueError:
raise ValueError("Instance value not a number")


def calcAlqueire(largura, comprimento):
try:
largura = float(largura)
comprimento = float(comprimento)
alqueires = ((largura * comprimento) / 24200)

#if isinstance(alqueires.is_integer(), int) and alqueires.is_integer():
if isinstance(alqueires, float) and alqueires.is_integer():
return round(alqueires)
else:
return round(alqueires, 2)

except ValueError:
raise ValueError("Instance value not a number")


def calcHectare(alqueire):
try:
alqueire = float(alqueire)
hectares = (alqueire * 2.42)

if isinstance(hectares, float) and hectares.is_integer():
return int(hectares)
else:
return round(hectares, 2)

except ValueError:
raise ValueError("Instance value not a number")


def calcProportion(comprimento, largura):
try:
comprimento = float(comprimento)
largura = float(largura)

proportion = float(comprimento / largura)

if proportion.is_integer():
return int(proportion)
else:
return round(proportion, 2)

except ValueError:
raise ValueError("Instance value not a number")

def main():
# Função que transforma alqueires em metros quadrados
metros_quadrados = metrosQuadrados(10)

# Calcula área quadrada com proporção 1:1
lado_area = calcQuadrado(metros_quadrados)
area_quadrada = calcAlqueire(lado_area, lado_area)
proportion = calcProportion(lado_area, lado_area)
hectares = calcHectare(area_quadrada)

print(f"\nDimensões área quadrada (Proporção {proportion}:1):")
print(f"Largura....: {lado_area:.2f} metros")
print(f"Comprimento: {lado_area:.2f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_quadrada} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")

# Vetor com as proporções
proportions = [1.5, 1.21, 2.0, 2.21, 2.42, 2.5, 3.0, 4.0, 4.5, 4.84, 5.0]

# Itera sobre todas as proporções e faz os cálculos
for prop in proportions:
# Calcula a área retangular com a proporção atual
largura, comprimento = calcRetangulo(metros_quadrados, prop)
metros_quadrados = metrosQuadrados(largura, comprimento)
area_retangular = calcAlqueire(largura, comprimento)
proportion = calcProportion(comprimento, largura)
hectares = calcHectare(area_retangular)

# Exibe as dimensões calculadas
print(f"\nDimensões área retângular (Proporção {proportion}:1):")
print(f"Largura....: {largura:.0f} metros")
print(f"Comprimento: {comprimento:.0f} metros")
print(f"Hectares...: {hectares} ha.")
print(f"Alqueires..: {area_retangular} alq.")
print(f"Metros²....: {metros_quadrados} m²\n")


if __name__ == "__main__":
main()



Em relação a esta lógica utilizada percebi que se o valor de ponto flutuante for arredondado para cima, retornando um inteiro, teoricamente funciona em algums casos:

if isinstance(hectares, float) and hectares.is_integer():


Teria como melhorar mais este codigo?

_________________________________________________________
Always listen the Buck!
Enquanto o cursor estiver pulsando, há vida![/quote


wiki.anon


12. Re: Melhorando a precisão de valores flutuantes em python[AJUDA]

César
dark777

(usa Debian)

Enviado em 26/11/2024 - 00:31h

aguamole escreveu:

Ele esta reclamando do ponto flutuante ou ele está reclamando dos valores?


na verdade estou tentando evitar isso:

Alqueires..: 1.4999999999999998 alq.


Fazendo com que retorne corretamente o valor abaixo:

Alqueires..: 1.49 alq.
ou
Alqueires..: 1.50 alq.


Apenas as duas casas decimais seriam arredondadas para cima, então "1.4999999" retornaria "1.50" arredondado para cima, e para o valor "1.5000002" retornaria "1.50", e nao algo como "1.51", tentei adicionar "0.01" mas nao funciona em todos os casos pois as proporçoes mudam conforme cada medida.

wiki.anon



01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts