11.18 求数字二进制形式中1的个数

发布于 2 天前  8 次阅读


#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

void count1(int n) {
	int count = 0;
	while (n) {
		count += n & 1;
		n >>= 1;
	}
	printf("%d", count);
}

int main() {
	int n;
	scanf("%d", &n);
	count1(n);
	return 0;
}

但是你应该知道,while(n)这个循环条件对负数是无效的

他右移是补1,而不是补0,这导致循环不会正常结束

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

void count1(unsigned int n) {
    int count = 0;
    while (n) {
        count += n & 1; // 检查 n 的最低位是否为 1
        n >>= 1;        // 右移 n,去掉最低位
    }
    printf("%d\n", count); // 打印 1 的个数
}

int main() {
    int n;
    printf("请输入一个整数: ");
    scanf("%d", &n); // 从标准输入读取一个整数
    count1((unsigned int)n); // 将 n 转换为无符号整数并传递给 count1
    return 0; // 返回 0,表示程序正常结束
}

//位运算符是聪明的,他知道怎么处理负数

//当你将一个负数强制转换为无符号整数时,其二进制表示(即补码)并不会改变,改变的是编译器对他的解释方式


解释方式的变化

  • 负数的解释:在补码表示中,11111111 11111111 11111111 11111111 被解释为 -1。这是因为最高位(符号位)为 1,表示这是一个负数
  • 无符号整数的解释:当你将其转换为 unsigned int 时,计算机不再考虑符号位,而是将所有位都视为有效的数值位。因此,11111111 11111111 11111111 11111111 被解释为 4294967295

所以,在这里,强制转换后,右移运算符是在前面补0,而不是补1,这就可以让循环正常结束了

届ける言葉を今は育ててる
最后更新于 2024-11-18