是否有任何现代平台具有非IEEE C/C++浮点格式?

mpgws1up  于 7个月前  发布在  C/C++
关注(0)|答案(4)|浏览(115)

我正在写一个视频游戏Humm and Strumm,它需要在游戏引擎中加入网络组件。我可以很容易地处理endianness中的差异,但在尝试处理可能的float内存格式时却遇到了障碍。我知道现代计算机都有一个标准的整数格式,但我听说它们可能并不都使用IEEE标准的浮点整数。这是真的吗?
当然,我可以将它作为字符串输出到每个数据包中,但我仍然必须转换为每个客户端的“众所周知的格式”,而不管平台如何。标准的printf()atod()是不够的。
请注意,因为这个游戏是一个自由/开源软件程序,将运行在GNU/Linux,*BSD和Microsoft Windows,我不能使用任何专有的解决方案,也没有任何单一平台的解决方案。
干杯,
帕特里克

0h4hbjxa

0h4hbjxa1#

我认为可以安全地假设每个平台都有可以依赖的IEEE-754规范的实现。然而,即使它们都实现了相同的规范,也不能保证每个平台都有完全相同的实现,设置了相同的FP控制标志,进行了相同的优化,或者实现了相同的非标准扩展。这使得浮点确定性很难控制,并且在这种情况下使用有点不可靠(在这种情况下,您将通过网络传递FP值)。
有关这方面的更多信息;读取http://gafferongames.com/networking-for-game-programmers/floating-point-determinism/
另一个需要解决的问题是处理没有浮点单元的客户端;大多数时候,这些将是低端CPU,控制台或嵌入式设备。如果你想瞄准他们,一定要考虑到这一点。FP模拟可以完成,但往往是非常缓慢的这些设备上,所以你必须得到一个挂起做定点计算。但请注意:编写精心设计的类来将浮点和定点计算抽象到同一代码中听起来像是一个计划,但在大多数设备上,这并不是一个好计划。它不允许您在处理固定点值时挤出最大精度和性能。
另一个问题是处理浮点值的字节序,因为你不能只是交换字节,然后再次在浮点寄存器中堆栈“m”(字节可能会有不同的含义,参见http://www.dmh2000.com/cpp/dswap.shtml)。
我的建议是将浮点数转换为定点中间值,如果需要的话做一个字节序校正并传输。另外,不要假设在不同机器上的两个浮点计算会产生相同的结果;他们不会的然而,除了IEEE-754之外,浮点实现是罕见的。例如,GPU倾向于使用定点,但现在更有可能使用IEEE-754的子集,因为它们不想处理被零除的异常,但它们将扩展适合16位的半浮点数。
另外,要知道有一些库已经为您解决了这个问题(在游戏环境中发送低级数据格式)。一个这样的库是RakNet:具体来说,它的BitStream类被设计为将这些类型的数据可靠地发送到不同的平台,同时将开销保持在最低限度。例如,RakNet经历了相当多的麻烦,不浪费任何带宽发送字符串或向量。

vc6uscn9

vc6uscn92#

如果你正确地抽象了你的网络接口,你就可以拥有序列化和非序列化浮点数据流的函数/对象。在我能想到的每一个系统上,这些都是IEEE标准,所以你只需要让它们不加修改地传递数据(编译器甚至可能会优化它,所以你不会损失任何性能)。如果你遇到一些不同格式的系统,你可以在这些函数中有条件地编译一些代码,以进行位黑客操作,将IEEE标准转换为本地格式。你只需要在一个地方改变它。你可能永远不需要这样做,但是,除非你进入控制台/手持设备/等。

nmpmafwu

nmpmafwu3#

有些嵌入式处理器根本不包含任何浮点硬件。对于台式机,我看不出有任何理由担心太多,除了细节,只有真正惹恼Maven(sqrt被错误地四舍五入的阿尔法,这类事情。让他们烦恼的是操作的实现,而不是格式)。
平台之间的一个变化与 * 反正规 * 的处理有关。即使这样也没有我想象的那么糟糕。

vsaztqbk

vsaztqbk4#

是否有任何现代平台具有非IEEE C/C++浮点格式?
也许直到201 x年初,一个很好的嵌入式目标编译器是CCS。它使用了non IEEE float
第1字节:8位指数
第2个字节:符号位和 * 尾数 * 的7个MS位
第3个字节:8位 * 尾数 *
第4字节:8个LS位 * 尾数 *
IIRC也不支持subnormal。任何00-XX-XX-XX都是“零”。

相关问题