好吧,我不相信 C++ 有任何真正安全的方式来存储浮点数而不会出现某种问题。在机器之间移动时,既高效又易于存储,无需使用大存储容量。
它非常准确,但它不支持真正疯狂的值。在任何位置,您最多可以有 7 位数字,但两边不能超过 7 位数字。对于左侧,您将收到不准确的结果。在右侧,您会在读取期间收到错误消息。要解决该错误,您可以在写入期间抛出错误或在读取时执行“buffer[idx++] & 0x7”,以防止其超出 0 和 7 范围。请记住,“& 0x7”仅有效,因为它是 2 减 1 的幂。即 2^3 - 1。您只能使用这些值来执行此操作,例如 0、1、3、7、15、31、63、127、255、511、1023 等...
因此,是否要使用它取决于您。我觉得这是获得您所需要的大多数价值的安全方式。下面的示例显示了如何将其转换为 4 字节数组,但对于 C++,这将是一个 char*。如果您不想执行除法,您可以将 POWERS_OF_TEN 数组转换为带有小数和倍数的辅助数组。
const float CacheReader::POWERS_OF_TEN[] =
{
1.0F, 10.0F, 100.0F, 1000.0F, 10000.0F, 100000.0F, 1000000.0F, 10000000.0F
};
float CacheReader::readFloat(void)
{
int flags = readUnsignedByte();
int value = readUnsignedTriByte();
if (flags & 0x1)
value = -value;
return value / POWERS_OF_TEN[(flags >> 1) & 0x7];
}
unsigned __int32 CacheReader::readUnsignedTriByte(void)
{
return (readUnsignedByte() << 16) | (readUnsignedByte() << 8) | (readUnsignedByte());
}
unsigned __int8 CacheReader::readUnsignedByte(void)
{
return buffer[reader_position] & 0xFF;
}
void CacheReader::writeFloat(float data)
{
int exponent = -1;
float ceiling = 0.0F;
for ( ; ++exponent < 8; )
{
ceiling = (POWERS_OF_TEN[exponent] * data);
if (ceiling == (int)ceiling)
break;
}
exponent = exponent << 0x1;
int ceil = (int)ceiling;
if (ceil < 0)
{
exponent |= 0x1;
ceil = -ceil;
}
buffer[writer_position++] = (signed __int16)(exponent);
buffer[writer_position++] = (signed __int16)(ceil >> 16);
buffer[writer_position++] = (signed __int16)(ceil >> 8);
buffer[writer_position++] = (signed __int16)(ceil);
}