c - C 中大小整数的算术和按位操作

标签 c int bit-manipulation

当您进行基本算术和按位运算时,我对 C 语言如何处理不同大小的整数有点困惑。如果在这种情况下会发生什么:

int8_t even = 0xBB;
int16_t twice = even << 8;
twice = twice + even; 

如果我采取另一种方式并尝试将 16 位 int 添加到 8 位怎么办?普通的 int 声明是动态的吗?为什么我要指定尺寸?当我添加两个都是 0xFF 的 8 位整数时会发生什么?

最佳答案

正如我在评论中提到的,在算术过程中所有内容都至少提升为 int。

这是一个示例程序来演示:

main(){
    struct {
        char x : 1;
    }t;
    t.x = 1;
    int i = t.x << (sizeof i * 8 - 1);
    printf("i = %x\n",i);
}

t.x 只有一位,但在此操作中,它会一直提升为整数以给出输出:

i = 80000000

另一方面,如果我们添加行

long long j = t.x << (sizeof j * 8 - 1)

gcc 给了我警告:

warning: left shift count >= width of type [enabled by default]

如果我采取另一种方式并尝试将 16 位 int 添加到 8 位怎么办?

所有算术都将以整数精度(可能是 32 位)完成,然后结果的底部 8 位将存储在 8 位数字中。

普通的 int 声明是动态的吗?

没有。它在实现上是固定宽度的(在您的实现上可能是 32 位)。

为什么我要指定尺寸?

也许您有空间限制。也许你的算法是为了处理特定大小的整数而设计的。也许您确实想处理 uint16_t (Z_65536) 提供的某些模字段。

当我添加到都是 0xFF 的 8 位整数时会发生什么?

这里的提升并不重要,8位结果将是0xFE。如果您要将结果存储在 16 位数字中,则结果将为 0x1FE(除非您的实现中的 int 只有 8 位。除了某些深奥的嵌入式应用程序之外,这种情况极不可能发生)。

编辑

我在这里写了关于无符号约定的内容,因为您将数字表示为 0xFF 似乎是指无符号数字(在 K&R C 中 0xFF 实际上是一个无符号文字)。如果您实际上指的是有符号的 8 位值 0xFF(相当于 -1),那么您的问题就变得微不足道了。无论整数有多大,它都应该始终能够表示 -1,以及 -1 + (-1) = -2 (实际上只需要两位来表示这些数字)。

关于c - C 中大小整数的算术和按位操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23134958/

相关文章:

c - long long Integer 的乘法错误是什么?

java - 检查数字的二进制表示形式中所有设置位后仅跟随未设置位的最佳方法

C:当 A >1 时,语句 'return A || 1' 会返回什么?

c - C 的日志记录库

有人可以解释为什么我的第一个打印 0,但在 *p = 6.35 之后,它可以打印 6.35?

python - 如何避免错误的输入/输出文件名以及 C 程序中的错误参数

MySQL:插入 float ,最后是一个整数

MySQL 整数存储要求

java - 给定掩码大小,有效地创建具有低位集的掩码

algorithm - (x % 64) == (x & 63) 背后的基本原理是什么?