【问题标题】:why the input argument on population count must be unsigned为什么人口计数的输入参数必须是无符号的
【发布时间】:2012-10-25 19:10:53
【问题描述】:
int pcount_r (unsigned x) {
    if(x==0)
        return 0;
    else
        return ((x & 1) + pcount_r(x >> 1));
}

只是想知道为什么输入参数是无符号的。

最好的问候!

【问题讨论】:

  • 右移和符号位!哒哒

标签: c algorithm assembly count population


【解决方案1】:

当 E1 具有带符号类型和负值 (C99 6.5.7:5) 时,E1 >> E2 产生的内容由实现定义。另一方面,E1 >> E2 由标准明确定义。接受无符号整数并对其进行操作是使函数最可移植的一种方法。

顺便说一下,通常使用无符号类型进行位旋转。

【讨论】:

  • 可以解释得更清楚,我的意思是傻瓜
  • @DanielGómezJurado int >> shift == crapunsigned >> shift == rulez
【解决方案2】:

如果数字有符号,则右移将复制符号位(最后一位),从而有效地为负数提供无限位数。

int pcount_r(int x) {
    if (x == 0)
        return 0;
    else if (x < 0)
        return sizeof(int)*8 - pcount_r(~x);
    else
        return (x & 1) + pcount_r(x >> 1);
}

【讨论】:

  • 是的。我现在才明白:D,只是一个问题,in -> pcount_r(~x),~是什么意思
  • ~ ("bitwise not") 反转数字的所有位,包括符号位。
【解决方案3】:

问题在于 C(与 Java 不同)不支持有符号(算术)移位。 CPU 有两种不同类型的移位运算符,有符号和无符号。例如,在 x86 上,SAR 指令执行算术右移,而 SHR 执行无符号右移。由于 C 只有一个右移运算符(>>),它不能同时支持它们。如果编译器使用无符号移位 (SHR) 实现上述代码,并且您向该过程提供负数,您将得到错误的答案。

【讨论】:

  • 相反——如果它使用shr,它总是是正确的。当使用sar 并且输入设置了符号位时,就会出现问题,算法永远不会终止。
  • “C 只有一个右移运算符 (>>),它不能同时支持它们” 我不明白这与说“C 只有一个加法 (+),所以它不能同时支持整数和浮点”。事实上,将&gt;&gt; 编译为 SAR 或 SHR 的选择是由编译器通过应用完全相同的规则来决定的,这些规则允许它确定是打算进行整数还是浮点计算。 C99 6.3.1.8:“许多期望算术类型操作数的运算符会导致转换并以类似方式产生结果类型。目的是确定一个常见的真实类型……”
  • @harold 如果使用 SAR,则程序将正确终止,因为 1/2 = 0 与 SAR。如果使用 SHL,那么程序也会终止,但会给出错误的答案,因为符号位会将计数加一。
  • @TylerDurden 1 >> 1 = 0,但 -1 >> 1 = -1(使用 sar)。至于符号位加一,嗯,它是开启的,所以你必须数一下,对吧?
  • @Pascal Cuoq C 标准没有定义如何解释“>>”。这样做的原因是,在过去,“>>”直接映射到 CPU 上的 SHR,在某些 CPU 上它是算术移位,而在其他 CPU 上它是无符号的,因此无法预测结果会是什么.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-16
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多