当用两种不同的方法将一个整数除以二的幂时,我得到两种不同的输出.

#include <stdio.h>

int main(void) {
  int y1 = 0x00061290;
  int y2 = 0xFFFE1A32;
  printf("(y1/(1<<k))=%x\n", (y1/(1<<5)));
  printf("(y2/(1<<k))=%x\n", (y2/(1<<5)));
  printf("(y1>>k))=%x\n", (y1>>5));
  printf("(y2>>k))=%x\n", (y2>>5));
  return 0;
}

输出:

(y1/(1<<k))=3094
(y2/(1<<k))=fffff0d2
(y1>>k))=3094
(y2>>k))=fffff0d1

当y1为0x00061290时,该整数的输出相同.

我想这是因为y1是正的,y2不是.但我不确定.有人能告诉我在什么情况下他们是不同的,在什么情况下他们是相同的吗?如果可能的话,解释两种操作的区别.谢谢

推荐答案

得到不同输出的原因是y1y2被定义为int,而不是unsigned int.有符号除法向0舍入(自C99起指定),而将负值向右移向负无穷大on your platform.C标准规定将负值向右移动的行为为implementation defined.

然而,请注意,为%x格式传递intprintf具有未定义的行为.

如果将y1y2定义为unsigned,则除法和移位将产生相同的结果.

以下是修改后的版本:

#include <stdio.h>

int main() {
    unsigned y1 = 0x00061290;
    unsigned y2 = 0xFFFE1A32;
    printf("y1=%x, y1/(1<<k)=%x\n", y1, y1 / (1<<5));
    printf("y2=%x, y2/(1<<k)=%x\n", y2, y2 / (1<<5));
    printf("y1=%x, y1>>k=%x\n", y1, y1 >> 5);
    printf("y2=%x, y2>>k=%x\n", y2, y2 >> 5);
    printf("\n");
    int i1 = 511;
    int i2 = -511;
    printf("i1=%d, i1/(1<<k)=%d\n", i1, i1 / (1<<5));
    printf("i2=%d, i2/(1<<k)=%d\n", i2, i2 / (1<<5));
    printf("i1=%d, i1>>k=%d\n", i1, i1 >> 5);
    printf("i2=%d, i2>>k=%d\n", i2, i2 >> 5);
    return 0;
}

输出:

y1=61290, y1/(1<<k)=3094
y2=fffe1a32, y2/(1<<k)=7fff0d1
y1=61290, y1>>k=3094
y2=fffe1a32, y2>>k=7fff0d1

i1=511, i1/(1<<k)=15
i2=-511, i2/(1<<k)=-15
i1=511, i1>>k=15
i2=-511, i2>>k=-16

C++相关问答推荐

FFmpeg不检测比特流过滤器参数

定义_MISIX_C_SAL时,在MacOS上编译失败,并出现奇怪错误

如何将一个enum类型类型转换为另一个类型?

我可以动态分配具有空类型函数的矩阵吗?

为什么静态说明符为内联函数生成外部定义?

设计处理各种数据类型的方法和数据 struct

strftime函数中%s的历史意义是什么?为什么没有记录?

我编译了一个新的c程序,并收到以下错误

为什么输出不是从上到下C

将指针作为参数传递给函数

使用C时,Windows CMD中的argc参数是否包含重定向命令?

为什么GCC C23中的关键字FALSE不是整数常量表达式?

为什么即使在强制转换时,此代码也会溢出?

如何捕捉只有换行符或空格字符缓冲区的边缘大小写

如何在ASM中访问C struct 成员

Flose()在Docker容器中抛出段错误

用C语言计算文本文件中的整数个数

无法访问共享目标文件内的共享指针

从Raku nativecall调用时精度不同

保存有符号整数结果的变量是否会溢出(后增量的副作用),并且此后从未在任何表达式中使用过它,是否会导致 UB?