我正在通过这个例子,它有一个函数输出一个十六进制位模式来表示任意浮点数.
void ExamineFloat(float fValue)
{
printf("%08lx\n", *(unsigned long *)&fValue);
}
Run Code Online (Sandbox Code Playgroud)
为什么要取fValue的地址,转换为无符号长指针,然后取消引用?是不是所有的工作都等同于直接转换为无符号长?
printf("%08lx\n", (unsigned long)fValue);
Run Code Online (Sandbox Code Playgroud)
我试过了,答案不一样,很困惑.
Dan*_*our 28
(unsigned long)fValue
Run Code Online (Sandbox Code Playgroud)
根据"通常的算术转换",这会将float值转换为值unsigned long.
*(unsigned long *)&fValue
Run Code Online (Sandbox Code Playgroud)
这里的目的是获取fValue存储的地址,假设在该地址中没有float但是unsigned long在该地址,然后读取该地址unsigned long.目的是检查用于存储float内存的位模式.
如图所示,这会导致未定义的行为.
原因:您可能无法通过指向与对象类型"不兼容"的类型的指针来访问对象."兼容"类型例如是(unsigned)char和每个其他类型,或共享相同初始成员的结构(在此处说到C).有关详细(C11)列表,请参阅§6.5/ 7 N1570(请注意,我对"兼容"的使用与参考文本中的使用不同 - 更广泛.)
解决方案:转换为unsigned char *,访问对象的各个字节并组装unsigned long出来:
unsigned long pattern = 0;
unsigned char * access = (unsigned char *)&fValue;
for (size_t i = 0; i < sizeof(float); ++i) {
pattern |= *access;
pattern <<= CHAR_BIT;
++access;
}
Run Code Online (Sandbox Code Playgroud)
注意(如@CodesInChaos指出的那样)上面将浮点值视为首先存储其最高有效字节("big endian").如果你的系统对浮点值使用不同的字节顺序,你需要调整它(或重新排列上面的字节,unsigned long对你来说更实用).
| 归档时间: |
|
| 查看次数: |
2448 次 |
| 最近记录: |