无符号字符的减法运算
Posted
技术标签:
【中文标题】无符号字符的减法运算【英文标题】:Subtraction operation on unsigned char 【发布时间】:2014-01-29 04:18:45 【问题描述】:我对 unsigned char 很好奇。我对 unsigned char 很好奇。我不小心对 unsigned char 进行了减法运算。我知道我不应该这样做。但我有点好奇一个特定的答案是怎么来的。任何人都可以在位级别上解释这一点吗?
unsigned char x = 150;
unsigned char y = 229;
unsigned char z = x - y;
最后我在调试过程中得到了 177 的 z
我在 Visual Studio 2008 中运行此代码。
【问题讨论】:
您确定您的代码中z
的类型是int
,而不是unsigned char
?如果是,请发布一个完整且可编译的示例来重现结果。
对不起,它是无符号字符。
【参考方案1】:
声明为无符号的无符号整数应遵守算术模 2^n 的定律,其中 n 是数字 该特定整数大小的值表示中的位数。
(C++11 标准,3.9.1.5)
在大多数平台上,unsigned char
是 8 位,因此结果是 150 - 229 mod 256 = -79 mod 256 = 177。
【讨论】:
【参考方案2】:是的,如果你从150
中减去229
,你最终会得到-79
。但是,由于目标限制在0..255
范围内(假设为 8 位),因此它会环绕以确保保持该范围。因此,您基本上将256
添加到-79
以结束177
。
换句话说,9 - 10
会给你一个有符号值的-1
,实际上给你一个 8 位的unsigned char
的255
。同样,9 - 11
会给你254
。
这与加法没有什么不同,255 + 7
给你6
,因为它在255
之后回绕到0
。
现在,规则比那个规则稍微复杂一点,因为可以将值提升为更大的数据类型,然后进行减法运算,然后截断结果。但是在数学上第一段是正确的。
【讨论】:
只有当z
的类型是unsigned char
时,你的推理才有效。最后一部分是完全错误的,算术运算符的操作数在执行算术运算之前进行整数提升。 Here's an example 这是如何工作的。
事实证明,z
毕竟是unsigned char
,所以你答案的第一部分是正确的。最后一段仍然是错误的,因为积分促销仍然适用。算术运算符不会对小于int
的任何东西进行运算。在实践中,编译器可能会看到结果被放入 unsigned char
并且不执行提升,假设操作在 char
s 上更有效。以上是关于无符号字符的减法运算的主要内容,如果未能解决你的问题,请参考以下文章