Na Unreal, quais são as diferenças entre o float do C ++ e o FFloat32?

17

Eu tenho tentado aprender alguns aspectos mais profundos do UE4 e ao ler muitos exemplos de códigos e também a base de código-fonte do mecanismo, notei que algumas vezes as pessoas (e o próprio código-fonte) usam a floatprimitiva C ++ padrão , mas algumas vezes usam a implementação personalizada da UE4 FFloat32.

Então fiquei curioso: ao programar um jogo com a Unreal, quais são as diferenças entre usar essas duas opções e, possivelmente, quais são os principais casos em que se deve abandonar a primitiva C ++ padrão em favor da implementação do mecanismo?

Kim Shutter
fonte
1
Eu estaria interessado em ler os exemplos que você achou que realmente usam FFloat32.
@ JoshPetrie Alguns deles estavam off-line, um casal estava online. Assim que eu tiver tempo em casa, vou procurá-los à parte
Kim Shutter

Respostas:

17

float, é um ponto flutuante em C ++. FFloat32é uma estrutura que representa um flutuador e (através de uma união) os campos de bits decompostos para as partes do sinal, mantissa e expoente desse flutuador.

Você geralmente nunca deve usar, FFloat32exceto quando:

  • você está usando alguma API que espera um FFloat32(estes são muito raros) ou
  • você precisa fazer algum tipo de invasão de bits de baixo nível com um valor de ponto flutuante (também bastante raro atualmente)

Não FFloat32é ruim , por si só, apenas não oferece realmente nada que você precisa para o uso de ponto flutuante de uso geral.

É menos comum do que um simples velho float, que tem algum impacto menor na legibilidade (outras pessoas podem não saber imediatamente para que serve imediatamente). Também não é convertido implicitamente em, floatportanto você digitará something.FloatValuemuito, o que também não é grande coisa, mas pode ser entediante.

Por fim, o uso de uniões e campos de bits não é portátil e é definido pela implementação (veja abaixo). Esse não é o seu problema, é tarefa da Epic garantir que o tipo seja estruturado para que seja utilizável em todas as implementações suportadas, mas é uma fonte potencial de erros se eles não conseguirem detectar um problema com a implementação do tipo quando um novo compilador A versão é lançada ou adicionada à lista de compiladores suportados.

Portanto, a menos que você precise brincar com os bits individuais na representação de ponto flutuante, provavelmente deve evitar FFloat32(seu primo FFloat16, pode ter um pouco mais de utilidade, pois não há um tipo de ponto flutuante C ++ de 16 bits padrão).

Costumava ser comum manipular carros alegóricos por meio de representações inteiras de seus componentes para " velocidade ". Os computadores modernos evitam grande parte dessa necessidade de muitas plataformas, e as várias técnicas de punção de tipo que podem ser usadas para fazer esse tipo de coisa podem, na verdade, ser prejudiciais ao desempenho ou à correção em qualquer caso.

Deve-se dizer que uma pesquisa no repositório GitHub da Unreal revela muito poucos usos do FFloat32tipo. Todos eles estão na definição de FFloat32si ou na definição de FFloat16.


Especificamente, FFloat32faz duas coisas que o padrão C ++ chama. Isto:

  • permite que você aja como se mais de um membro do sindicato estivesse ativo ao mesmo tempo; você deve escrever nos membros do ponto flutuante e ler a partir de um dos membros inteiros (9.5.1, [class.union])
  • espera que a alocação de campo de bits dentro da união corresponda à da alocação de bits de um valor de ponto flutuante IEEE; no entanto, a alocação e o alinhamento dos membros do campo de bits dentro de um tipo de classe é definida pela implementação (9.6.1, [class.bit])

fonte
O Unreal não é escrito em C ++ padrão, é escrito para os compiladores específicos para os quais foi escrito, desde que eles façam a coisa esperada, o padrão é irrelevante.
User253751
Eu esperaria que esses campos de bits fossem bastante portáteis, mesmo em C / C ++ padrão, pois são definidos por um padrão IEEE, e qualquer compilador que use um layout diferente nãofloat teria uma marca vermelha compatível com IEEE 754 (e problemas de compatibilidade com muitos softwares existentes )
Dmitry Grigoryev
3
O problema (pedante) é que a ordem escrita desses campos de bits pode corresponder ao padrão IEEE, mas o compilador C ++ pode reordená-los ou realinhá-los. Esta é apenas uma nota de rodapé menor, já que lidar com isso é o trabalho da Epic; eles devem monitorar cada nova versão do compilador para verificar se o tipo funciona corretamente.
@ JoshPetrie Point tomado, obrigado pelo esclarecimento.
Dmitry Grigoryev
1
@JustinLardinois Mas o FFloat32 contém um floatmembro do sindicato, portanto, se ele floatfor realmente maior que 32 bits, o total FFloat32também será bom, já que o sindicato deve ser grande o suficiente para conter o maior membro. Nos casos em que os flutuadores são maiores que quatro bytes, a Epic terá que modificar também as partes do campo de bits da união para resolver isso; caso contrário, eles não mapearão o flutuador completo.