Alguém pode explicar a representação de float na memória?

20

Esta não é uma pergunta duplicada, pois li a pergunta anterior.

Alguém pode me ajudar na compreensão how float values are stored in the memory.

Minha dúvida é aqui valores flutuantes contêm ' .'( for example 3.45) como o '.'será representado na memória?

Alguém pode me esclarecer com um diagrama?

user2720323
fonte
21
E a fonte menos esperada, a Wikipedia? en.wikipedia.org/wiki/Floating_point#Internal_representation
9000
4
E você pode adicionar o artigo principal: ponto flutuante IEEE
mouviciel 21/10
4
Se você é como eu, e você gostaria de aprender brincando com as coisas, colocando em entradas e receber saídas, etc, verificar este site: binaryconvert.com/convert_double.html
KChaloux
Há uma ampla variedade de formatos de ponto flutuante, todos diferentes. O ponto flutuante do IEEE é o mais comum atualmente, mas não é o único. Quando eu estava na graduação, tive que aprender o formato de ponto flutuante CDC 6600, e ele tinha algumas vantagens sobre o IEEE, o maior deles com 48 bits de mantissa para precisão única. O IEEE é limitado a cerca de 24 bits de mantissa para precisão única, e é por isso que todas as aulas introdutórias de métodos numéricos nos dias de hoje dizem aos alunos "Sempre use o dobro, não flutue".
John R. Strohm
Veja floating-point-gui.de e lembre-se de que URL
Basile Starynkevitch

Respostas:

44

O ponto decimal não é explicitamente armazenado em nenhum lugar; isso é um problema de exibição.

A explicação a seguir é uma simplificação; Estou deixando de fora muitos detalhes importantes e meus exemplos não devem representar nenhuma plataforma do mundo real. Ele deve fornecer uma amostra de como os valores de ponto flutuante são representados na memória e os problemas associados a eles, mas você deseja encontrar fontes mais autorizadas, como o que todo cientista da computação deve saber sobre aritmética de ponto flutuante .

Comece representando um valor de ponto flutuante em uma variante da notação científica, usando a base 2 em vez da base 10. Por exemplo, o valor 3.14159 pode ser representado como

    0,7853975 * 2 2

0,7853975 é o significando , também conhecido como mantissa; é a parte do número que contém os dígitos significativos. Este valor é multiplicado pela base 2 elevada à potência de 2 para obter 3,14159.

Os números de ponto flutuante são codificados armazenando o significando e o expoente (junto com um bit de sinal).

Um layout típico de 32 bits se parece com o seguinte:

 3 32222222 22211111111110000000000
 1 09876543 21098765432109876543210
+-+--------+-----------------------+
| |        |                       |
+-+--------+-----------------------+
 ^    ^                ^
 |    |                |
 |    |                +-- significand 
 |    |
 |    +------------------- exponent 
 |
 +------------------------ sign bit

Como tipos inteiros assinados, o bit de ordem superior indica sinal; 0 indica um valor positivo, 1 indica negativo.

Os próximos 8 bits são usados ​​para o expoente. Os expoentes podem ser positivos ou negativos, mas em vez de reservar outro bit de sinal, eles são codificados de forma que 10000000 represente 0, portanto 00000000 represente -128 e 11111111 represente 127.

Os bits restantes são usados ​​para o significando. Cada bit representa uma potência negativa de 2 contando da esquerda, portanto:

    01101 = 0 * 2 -1 + 1 * 2 -2 + 1 * 2 -3 + 0 * 2 -4 + 1 * 2 -5 
          = 0,25 + 0,125 + 0,03125 
          = 0,40625

Algumas plataformas assumem um bit inicial "oculto" no significando que é sempre definido como 1, portanto, os valores no significando estão sempre entre [0,5, 1). Isso permite que essas plataformas armazenem valores com uma precisão um pouco maior (mais sobre isso abaixo). Meu exemplo não faz isso.

Portanto, nosso valor de 3,14159 seria representado como algo como

    0 10000010 11001001000011111100111
    ^ ^ ^
    | | |
    | | + --- significando = 0,7853975 ...
    | |
    | + ------------------- expoente = 2 (130 - 128)
    |
    + ------------------------- sign = 0 (positivo)

    valor = -1 (sinal) * 2 (expoente) * (significando)
    valor = -1 0 * 2 2 * 0,7853975 ...
    valor = 3.14159 ...

Agora, algo que você notará se somar todos os bits no significado é que eles não totalizam 0,7853975; eles realmente chegam a 0,78539747. Não há bits suficientes para armazenar exatamente o valor ; só podemos armazenar uma aproximação. O número de bits no significando determina a precisão ou quantos dígitos significativos você pode armazenar. 23 bits nos fornece aproximadamente 6 dígitos decimais de precisão. Os tipos de ponto flutuante de 64 bits oferecem bits suficientes no significado e fornecem aproximadamente 12 a 15 dígitos de precisão. Mas esteja ciente de que existem valores que não podem ser representados exatamente, não importa quãomuitos bits que você usa. Assim como valores como 1/3 não podem ser representados em um número finito de dígitos decimais, valores como 1/10 não podem ser representados em um número finito de bits. Como os valores são aproximados, os cálculos com eles também são aproximados e os erros de arredondamento se acumulam.

O número de bits no expoente determina o intervalo (os valores mínimo e máximo que você pode representar). Porém, à medida que você avança em direção aos seus valores mínimos e máximos, o tamanho da diferença entre valores representáveis ​​aumenta. Ou seja, se você não puder representar exatamente valores entre 0,785397 e 0,785398, também não poderá representar exatamente valores entre 7,85397 e 7,85398 ou valores entre 78,5397 e 78,5398 ou valores entre 785397,0 e 785398,0. Tenha cuidado ao multiplicar números muito grandes (em termos de magnitude) por números muito pequenos.

John Bode
fonte
"mas em vez de reservar outro bit de sinal" O que você está descrevendo é o comportamento exato de um número inteiro assinado.
7187 Simon
6

O .não é armazenado. Primeiro, você deve entender a notação de engenharia, que possui um fator de precisão fixa e um expoente inteiro: 1é 1,0 · 10 0 = 1.0E0, 2 é 2.0E0, 10 é 1.0E1etc. Isso permite uma notação muito curta de números grandes. Um bilhão é 1.0E9. O fator antes da Eé geralmente notada como um número de precisão fixa: 1.00000E9. Um resultado disso é que o número um bilhão e um = 1.000.000.001 e um bilhão são os mesmos nesta notação, quando a precisão não é grande o suficiente. Observe também que o fator nunca precisa de um zero inicial. Em vez disso, o expoente pode ser decrementado até que não seja mais esse o caso.

Na memória, um número de ponto flutuante é representado da mesma forma: um bit tem o sinal, alguns bits formam o fator como um número de precisão fixa ("mantissa"), os bits restantes formam o expoente. Diferenças significativas da notação de engenharia da base 10 é que, é claro, agora o expoente tem a base 2. O tamanho exato de cada parte depende do padrão exato de ponto flutuante que você está usando.

amon
fonte
3
Esta é "notação científica". "Notação de engenharia" é quando o expoente é restrito a múltiplos de 3.
Clement J.
7
Essa base 2 é usada é muito importante. Ele determina quais valores podem ser armazenados exatamente e quais não, e mesmo que você não se preocupe em desenvolver uma intuição para quais valores (eu sei que não posso), você deve pelo menos lembrar que os dígitos decimais são completamente inúteis maneira de pensar sobre carros alegóricos.
1
@ delnan: Se ajudar, cada bit na mantissa é metade do bit mais alto. Assim, os carros alegóricos podem armazenar somas de potências negativas de dois: 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 e assim por diante, até o limite da mantissa . Portanto, o epsilon em 32 bits floaté 2^-22 * exponentou cerca de 1/4194304.
greyfade