/ / A conversão de float para int é consistente em todas as plataformas e arquiteturas de processador? - c ++, c, ponto flutuante

A conversão de float para int é consistente em todas as plataformas e arquiteturas de processador? - c ++, c, ponto flutuante

Estou trabalhando em um jogo multiplayer que depende tantochamado "determinismo de ponto flutuante" ou, em outras palavras, o resultado de todos os cálculos deve ser exatamente o mesmo em todos os que estão executando o jogo. Isso significa essencialmente não usar o ponto flutuante IEEE 754, pois as operações podem resultar em valores diferentes, dependendo dos modos de arredondamento, do uso de instruções de adição múltipla combinada ou raiz quadrada inversa, implementações libc diferentes, etc.

Então, eu fui e fiz versões de ponto fixo de todosas operações aritméticas básicas e até algumas funções transcendentais. No entanto, eu ainda gostaria de usar literais de ponto flutuante para configurar variáveis ​​de jogo. Ao fazer isso, acabo com um código parecido com este para converter de ponto flutuante em ponto fixo:

explicit NetFixedPoint(float val)
{
static const StorageType kOne = StorageType(1) << FractionalBits;
m_Value = ((StorageType)(val * kOne));
}

Isso me dará o mesmo resultado em todas as plataformas e arquiteturas de processador?

Respostas:

5 para resposta № 1

A resposta curta é não".

A representação de ponto flutuante é definida pela implementação e o tipo de preocupação mencionado entre os tipos de ponto flutuante também ocorre ao converter valores de ponto flutuante em outros tipos.

Além disso, várias propriedades de int - incluindo tamanho, faixa de valores que ele pode representar e representação (por exemplo, organização de bits) também são definidos pela implementação.

O efeito líquido é que algumas conversões de float para int funcionará de maneira confiável entre implementações e algumas não "t". Alguns valores serão arredondados para baixo ao converter float para int. UMA float também pode representar uma faixa maior de valores que um inte a conversão de valores "fora do intervalo" pode gerar um comportamento indefinido.

Em vez de tentar usar literais de ponto flutuantepara inicializar suas variáveis, considere usar literais de string (e agrupar os valores entre aspas duplas). A desvantagem é a sobrecarga de analisar uma sequência para inicializar suas variáveis.


4 para resposta № 2

A conversão de ponto flutuante para inteiro é estritamente definida se o valor do ponto flutuante, truncado em direção a zero, é representável no tipo inteiro. Caso contrário, é indefinido.

As outras respostas parecem estar sendo intencionalmenteobtuso; se você depende de qualquer tipo de determinismo de ponto flutuante, precisa assumir uma implementação em conformidade com a IEEE-754, não a generalidade gratuita e falsa que o padrão C ++ permite para implementações que não estão em conformidade com a IEEE-754. Nesse caso, você tem um certo grau de determinismo, supondo que seu compilador não seja um buggy e que suas preocupações estarão em outras áreas além da flutuação para a conversão int.


1 para resposta № 3

Os detalhes da conversão de uma implementação de C ++de valores de ponto flutuante a valores inteiros é principalmente um ponto discutível, quando o padrão C ++ não oferece muita garantia sobre o valor de um ponto flutuante em primeiro lugar.

O padrão C ++ garante apenas que:

[básico.fundamental]

Existem três tipos de ponto flutuante: float, double e long double. O tipo double fornece pelo menos a mesma precisão que float, e o O tipo long double fornece pelo menos a mesma precisão que double. o O conjunto de valores do tipo float é um subconjunto do conjunto de valores de o tipo double; o conjunto de valores do tipo double é um subconjunto de o conjunto de valores do tipo long double. A representação do valor de tipos de ponto flutuante é definido pela implementação.

(ênfase minha)

Quando "o valor da representação detipos de ponto flutuante é definido pela implementação ", que praticamente exclui tudo. Você não tem nenhum tipo de garantia sobre a consistência da conversão de valor flutuante em número inteiro entre diferentes implementações de C ++, pois o padrão não oferece nenhuma garantia de que C ++ diferente implementações "os valores de ponto flutuante terão representações de valor consistentes em primeiro lugar!

Se você precisar de ponto flutuante bem definidosemântica, sua única opção realista é usar bibliotecas matemáticas de precisão especial e arbitrária, como o Gnu MP, onde você obtém controle completo sobre a precisão do ponto flutuante e as conversões de valor.