题目描述:
/*
*Generate mask indicating leftmost 1 in x. Assume w=32.
*For example 0xFF00 -> 0x8000, and 0x6600 -> 0x4000.
* If x = 0, then return 0.
*/
代码如下:
1 #include<stdio.h> 2 int leftmost_one(unsigned x); 3 int main() 4 { 5 printf("Please enter number: "); 6 unsigned x; 7 scanf("%x",&x); 8 int i = leftmost_one(x); 9 printf("%x\n",i); 10 return 0; 11 } 12 13 int leftmost_one(unsigned x) 14 { 15 x |= x >> 1; 16 x |= x >> 2; 17 x |= x >> 4; 18 x |= x >> 8; 19 x |= x >> 16; 20 return x-(x >> 1); 21 }
代码分析:
这道题目其实不难,难就难书上对题目的要求。如果没这些要求,那么这道题目可以简单的写成这样,代码如下:
1 #include<stdio.h> 2 int left_max(unsigned x); 3 int main() 4 { 5 printf("Please enter number: "); 6 unsigned x; 7 scanf("%x",&x); 8 int i = left_max(x); 9 printf("%x\n",i); 10 return 0; 11 } 12 13 int left_max(unsigned x) 14 { 15 int i; 16 for(i = 32;i >= 0;i--) 17 { 18 if(x & (1 << i)) 19 { 20 return 1 << i; 21 } 22 } 23 return 0; 24 }
这样就简单,不过既然要求就这样,那我们只能老老实实的按要求写了。
首先我们用一个具体数据来测试 leftmost_one() 这个函数,比如用0xFF,这个数的二进制表示为1111111100000000。
第一次或操作:
x:
0000 0000 0000 0000 1111 1111 0000 0000
|
x>>1:
0000 0000 0000 0000 0111 1111 1000 0000
=
0000 0000 0000 0000 1111 1111 1000 0000
接下来的四次或操作,我们就不一一写出来,给出最后的结果为0000 0000 0000 0000 1111 1111 1111 1111 1111,我们观察结果和原数的差别,发现原数位为1的,结果对应的位也为1。而在位值为1的最左的位,右边位值为0的位的位值也变成1。即原数由[00..0011..1100..00],变成了[00..0011..1111..11]的形式。为什么能得出这样的结果,因为或操作保证原数位值为1的位不变,位值为0的位可能被转换为1。而右移操作保证只作用想要作用的位置,即位值为1的最左的位的右边。
至于为什么从右移1到右移16?我不是太明白,但我想可能是为了保证不漏位吧。因为在我用的这个数据0xFF,在第四次或操作,得出的结果就已经是0xFFFF,懂的朋友请不舍赐教,先感谢了。
再得出0xFFFF,接下来就很简单了,可以用 x-(x >> 1),得出想要的结果。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)