为什么这种计算整数体系结构符号的方法是特定的?
why is this method for computing sign of an integer architecture specific
从这里的链接计算整数的符号
int v; // we want to find the sign of v
int sign; // the result goes here
sign = v >> (sizeof(int) * CHAR_BIT - 1);
// CHAR_BIT is the number of bits per byte (normally 8)
如果我理解正确的话,如果sizeof(int) = 4 bytes => 32 bits
MSB或第32位为该符号保留。所以,我们右移(sizeof(int) * CHAR_BIT - 1),所有的位都从右边掉下来,只留下索引0处的前MSB。如果MSB为1 => v为负,则为正
我的理解正确吗?
如果是这样,那么有人可以解释一下作者在这里所说的这种方法是特定于架构的是什么意思吗?
这个技巧是有效的,因为当有符号整数向右移动时最左位的值被复制到其他位。最左派当该值为负时为1,否则为0;所有1位给出1。不幸的是,这个行为是特定于体系结构的。
我认为"体系结构相关"是基于处理器支持的移位操作类型。X86(16、32和64位模式)支持"算术移位"answers"逻辑移位"。算术变体在移动时向下复制移位值的顶部位,逻辑移位则不会,而是用零填充。
但是,为了避免编译器不得不生成如下代码:
int temp = (1 << 31) & v;
sign = v;
for(i = 0; i < 31; i++)
sign = temp | (sign >> 1);
以避免架构只有"逻辑"转换的问题。
大多数体系结构都有这两种变化,但有些处理器没有。(对不起,我找不到一个参考,显示哪些处理器有和没有两个变体的shift)。
64位机器也可能存在无法区分64位和32位移位的问题,因此移位的是数字的上32位,而不是较小的符号位。不确定这样的处理器是否存在。
另一部分当然是确定在1补数中-0的符号实际上是符号的"0"或"-1"结果。这取决于你想要做什么。
这是"依赖于体系结构的",因为在c++中,负值右移的效果是实现定义的(在C中它会产生未定义的行为)。反过来,这意味着您不能依赖结果,除非您已经阅读并理解了编译器的功能文档。就我个人而言,我相信编译器能够为v < 0 ? -1 : 0
生成适当的代码。
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 在C++中使用内联方法时出现未定义的符号错误
- 寻找一种更好的方法来表示无符号字符数组
- 在 std::vector<无符号字符中存储任意数据的方法>
- 使用192/256位整数求和无符号64位整数向量的点积的最快方法
- 仅在少数方法(静态或共享库)中解析的外部符号
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- 有没有一种预处理器的方法可以从调试符号中删除代码段
- 计算机使用什么方法添加无符号整数
- 为什么链接器报告全局函数的乘法定义符号,而不是类静态方法
- 为C++字符串中的特殊符号 (") 赋予文字含义的有效C++方法
- 在 C++/CLI 中从本机转换为管理无符号短的最快方法
- 为大无符号整数分配内存的有效方法
- 获取两个无符号整数 C++ 乘积的高 32 位的有效方法
- 根据浮点符号对浮点进行舍入的最简单方法是什么
- 在 cpp 正文中声明方法时未定义的符号
- 如果未使用方法本身,则忽略方法中的未定义符号
- 标准::字符串::空的未定义符号错误;Mac OS High Sierra 上的 c++ 标准方法链接错误