Os tipos de ponto flutuante (como Single e Double) são representados na memória por um sinal, uma mantissa e um expoente. Pense nisso como notação científica:
Sign*Mantissa*Base^Exponent
Eles - como você pode esperar - usam a base 2. Existem outros ajustes que permitem representar o infinito e o NaN, e o expoente é deslocado (retornará a isso), e uma abreviação para a mantissa (retornará a isso também) . Procure o padrão IEEE 754 que abrange sua representação e operações para obter mais detalhes.
Para nossos propósitos, podemos imaginá-lo como um número binário "mantissa" e um "expoente" que diz onde colocar o separador decimal.
No caso de Single, temos 1 bit para ele assinar, 8 para o expoente e 23 para a mantissa.
Agora, o importante é armazenar a mantissa a partir do dígito mais significativo. Lembre-se de que todos os zeros à esquerda não são relevantes. E, considerando que estamos trabalhando em binário, sabemos que o dígito mais significativo é 1 ※. Bem, como sabemos disso, não precisamos armazená-lo. Graças a essa abreviação, o alcance efetivo da mantissa é de 24 bits.
※: A menos que o número que estamos armazenando seja zero. Para isso, teremos todos os bits definidos como zero. No entanto, se tentarmos interpretar isso sob a descrição que eu dei, você teria 2 ^ 24 (o implícito 1) multiplicado por 1 (2 à potência do expoente 0). Portanto, para corrigi-lo, o expoente zero é um valor especial. Também existem valores especiais para armazenar o infinito e o NaN no expoente.
De acordo com o deslocamento do expoente - além de evitar os valores especiais -, com o deslocamento, é possível colocar o ponto decimal antes do início da mantissa ou após seu término, sem a necessidade de ter um sinal para o expoente.
Isso significa que, para números grandes, o tipo de ponto flutuante colocará o ponto decimal além do final da mantissa.
Lembre-se de que a mantissa é um número de 24 bits. Ele nunca representará um número de 25 bits ... não possui esse bit extra. Portanto, o único não pode distinguir entre 2 ^ 24 e 2 ^ 24 + 1 (esses são os primeiros números de 25 bits e diferem no último bit, que não é representado no único).
Assim, para números inteiros, o intervalo do único é -2 ^ 24 a 2 ^ 24. E tentar adicionar 1 a 2 ^ 24 resultará em 2 ^ 24 (porque, no que diz respeito ao tipo, 2 ^ 24 e 2 ^ 24 + 1 são o mesmo valor). Experimente online . É por isso que há uma perda de informações ao converter de número inteiro para único. E é também por isso que um loop que usa um único ou um duplo pode realmente ser um loop infinito sem você perceber.