移位计数操作允许的值是多少?

时间:2017-05-18 09:41:53

标签: c bit-shift

get

此代码将%example data a = 2; b = 1.45; x = linspace(0,1E4,1800); y = a*x.^b; y = y.*(1+randn(1,1800)*0.02); plot(x,y); f = @(x,p) p(1)*x.^p(2); %function sqerr = @(x,y,p) sum((y-f(x,p)).^2); %sum of squared errors p = [1,1]; %starting conditions vals=[]; for ct = 1800:-1:50 p = fminsearch(@(p) sqerr(x(1:ct),y(1:ct),p),p); %fit dev = (f(x(ct),p)-y(ct))/y(ct); %devation (can be negative as well!) if dev>0.0298&&dev<0.0302 vals=[vals,ct]; end end 作为输出。如果我写#include <stdio.h> int main(void) { unsigned int var=1; var = var<<32; printf("%u ",var); } ,它会产生1

如果我输入var = var<<31;然后2147483648,则会产生var = 12;。我从我的教科书(旧版本)中读到,ANSI C不允许在一次操作中将所有位移出一个值。

所有主要编译器的行为是否相同(将粘贴输入复制到输出),或者当我指示它执行var = var<<32;时,只有GCC会将粘贴12从输入复制到输出???

3 个答案:

答案 0 :(得分:5)

C11 6.5.7按位移位运算符

  

如果右操作数的值为负或大于或   等于提升的左操作数的宽度,行为是   未定义。

这意味着如果在这种情况下移位32位或更多位,则没有明确定义的行为。任何事情都可能发生,包括崩溃和奇怪的结果。

  

我从我的教科书(旧版本)中读到,ANSI C不允许在一次操作中将所有位移出一个值。

这是正确的,您必须执行几个位操作,例如x<<=16; x<<=16;以避免未定义的行为。

答案 1 :(得分:0)

GCC字面上说你回答: RewriteBase

此外,它取决于您使用的架构。您的问题已经回答here

答案 2 :(得分:0)

只是为了更深入一点:

经典地将C语言开发为“便携式汇编程序”。内置操作只是大多数CPU实现的操作,它们的语义为可移植性提供了最低的公分母。

几乎每个CPU都提供左移和右移操作。但是平台在溢出和负数等细节方面存在差异,因此C标准保留了未定义的极端情况。

特别是,对于大于寄存器宽度的移位计数,许多CPU仅使用所需的位数并截断其余位。当count是常量时,编译器可能会注意到未定义的行为,只是将操作丢弃为垃圾。