Qua*_*key 16 c++ floating-point casting
注意:我static_cast
原来错误地问过; 这就是为什么最重要的答案static_cast
首先提到的原因.
我有一些二进制文件,带有小的字节序浮点值.我想以与机器无关的方式阅读它们.我的字节交换例程(来自SDL)在无符号整数类型上运行.
在整数和浮点数之间简单投射是否安全?
float read_float() {
// Read in 4 bytes.
Uint32 val;
fread( &val, 4, 1, fp );
// Swap the bytes to little-endian if necessary.
val = SDL_SwapLE32(val);
// Return as a float
return reinterpret_cast<float &>( val ); //XXX Is this safe?
}
Run Code Online (Sandbox Code Playgroud)
我希望这个软件尽可能便携.
AnT*_*AnT 26
嗯,static_cast
是"安全的"并且已经定义了行为,但这可能不是你需要的.将整数值转换为float类型只会尝试在目标浮点类型中表示相同的整数值.即5
类型int
将变为5.0
类型float
(假设它可以精确表示).
您似乎要做的是float
在声明为Uint32
变量的内存块中构建值的对象表示.要生成结果float
值,您需要重新解释该内存.这将通过以下方式实现reinterpret_cast
assert(sizeof(float) == sizeof val);
return reinterpret_cast<float &>( val );
Run Code Online (Sandbox Code Playgroud)
或者,如果您愿意,也可以使用相同内容的指针版本
assert(sizeof(float) == sizeof val);
return *reinterpret_cast<float *>( &val );
Run Code Online (Sandbox Code Playgroud)
虽然这种类型惩罚不能保证在遵循严格别名语义的编译器中工作.另一种方法是这样做
float f;
assert(sizeof f == sizeof val);
memcpy(&f, &val, sizeof f);
return f;
Run Code Online (Sandbox Code Playgroud)
或者您可以使用众所周知的联合hack来实现内存重新解释.这在C++中是正式非法的(未定义的行为),这意味着此方法只能用于支持它作为扩展的某些实现
assert(sizeof(float) == sizeof(Uint32));
union {
Uint32 val;
float f;
} u = { val };
return u.f;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15199 次 |
最近记录: |