AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 78750919
Accepted
yahoic
yahoic
Asked: 2024-07-16 00:16:31 +0800 CST2024-07-16 00:16:31 +0800 CST 2024-07-16 00:16:31 +0800 CST

Como funciona o arredondamento na multiplicação de float?

  • 772

O valor exato de float 0.7fé 0.69999...
então pensei que o resultado 0.7f * 100fseria algo abaixo 70, como 69.99999...
Mas o resultado é exato 70 .
A multiplicação de float envolve tal arredondamento?

Em caso afirmativo, esse pós-processamento também é aplicável em ponto fixo?
Encontrei em algumas bibliotecas de ponto fixo, FP(100) * FP(0.7) is 69.99999.
Ao lançar isso para int, eles truncam impiedosamente e eu recebo 69. O que é indesejável, pois o FP pode expressar exato 70.

floating-point
  • 1 1 respostas
  • 48 Views

1 respostas

  • Voted
  1. Best Answer
    Steve Summit
    2024-07-16T03:27:24+08:002024-07-16T03:27:24+08:00

    O ponto flutuante binário de precisão finita não pode representar exatamente todos os números reais (ou decimais), mas deve sempre representar o número mais próximo possível .

    A aritmética de ponto flutuante de precisão finita também não pode calcular todos os resultados possíveis, mas é necessária (pelo menos em casos comuns) para calcular um resultado devidamente arredondado.

    O ponto flutuante de precisão simples exato (representado mais próximo) correspondente a 0,7 é 0b0.101100110011001100110011, que quando convertido novamente em decimal é 0,699999988079071044921875. Observe que esse número possui 24 bits significativos, o que faz parte da definição de precisão única IEEE-754.

    Multiplicar esse número por 100 nos daria 0b1000101.1111111111111111111011. Mas esse número tem 29 bits significativos, portanto não cabe nos 24 bits de significância disponíveis em precisão única. Então temos que arredondar. Agora, o 25º bit é 1, então arredondamos para cima, e quase todos os bits à esquerda desse 25º bit são 1, então ele arredonda para cima 0b1000110.00000000000000000, ou exatamente 70,0.

    Observe que, embora o ponto flutuante de precisão simples tenha 24 bits de significância, os cálculos envolvendo ponto flutuante de precisão simples devem ser realizados usando, temporariamente, mais de 24 bits de precisão, para que alguns bits além do 24 possam ser computados, para que o resultado pode ser arredondado corretamente, conforme necessário.

    E este é um bom exemplo de como as regras do IEEE-754 sobre resultados arredondados funcionam, e funcionam bem. É fácil ter a impressão (equivocada) de que os valores de ponto flutuante estão sempre pelo menos um pouco errados, se não totalmente quebrados . Mas, na verdade, a aritmética de ponto flutuante IEEE-754 geralmente é bastante precisa e se esforça para evitar que os erros se agravem - o que significa que, não raramente, os erros podem se anular, produzindo resultados exatos, afinal. Isso é basicamente o que acontece aqui.

    Ou, em outras palavras, a regra não é que os cálculos de ponto flutuante sejam sempre imprecisos. A verdadeira regra é que os cálculos de ponto flutuante às vezes são imprecisos – mas às vezes também são perfeitamente precisos.

    (Na verdade, uma regra ainda melhor é que os cálculos de ponto flutuante são muitas vezes imprecisos em comparação com um resultado esperado, mas decimal . Se você pegar dois números binários de ponto flutuante e fizer uma operação sobre eles, quase sempre obterá um resultado que é realmente preciso - em binário O que quero dizer é que a maioria das imprecisões aparentes ocorre apenas quando você compara o resultado binário com um que você calculou, de alguma outra forma, em decimal.)


    Se a explicação acima não funcionar para você, aqui está outra maneira de ver a questão. Como sabemos, as representações de ponto flutuante não podem representar todos os números. Na verdade, um dos números que eles não podem representar em binário é 0,7, e o número representável mais próximo em precisão simples é um número binário igual a 0,699999988079071044921875.

    Agora, e se pegarmos esse número 0,699999988079071044921875 e multiplicá-lo por 100? O resultado exato deve ser 69,9999988079071044921875. Mas este é outro número que não pode ser representado com exatidão. Se você pegar esse número não representável 69,9999988079071044921875 e perguntar qual seria o número mais próximo que pode ser representado exatamente com precisão simples, esse número é... 70,0! Em precisão simples, o próximo número representável menor que esse é 69,99999237060546875, que está mais distante (neste caso, mais de 5 vezes mais distante) do que 70,0.


    Você também perguntou sobre bibliotecas de ponto fixo. Aí a resposta dependeria obviamente da implementação, mas mais importante ainda, da base. Uma biblioteca binária de ponto fixo também não pode representar exatamente 0,7. Mas uma biblioteca decimal de ponto fixo obviamente poderia.

    Uma representação binária de ponto fixo "16,16" de 0,7 seria, eu acho, 0000000010110011(base 2), ou 00b3(base 16) ou 179 (base 10), que convertida novamente em uma fração é 0,69921875. Multiplicar isso por 100 dá 100010111101100// 45ec17900, que converte novamente para 69,921875. Portanto, sob essas suposições, não vejo uma maneira de fazer melhor (ou seja, uma maneira de obter 70,0).

    Mas se uma biblioteca decimal de ponto fixo fornecesse 69 após a multiplicação, eu diria que está muito mal implementada. Uma representação decimal de ponto fixo de 16 bits de 0,7 com um fator de escala de 100 seria 70, que quando multiplicado por 100 dá 7.000, que quando dividido pelo fator de escala novamente obviamente dá exatamente 70,0.

    • 3

relate perguntas

  • Representando um número menor que o menor em precisão única

  • Valores decimais dispersos em números reais

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve