找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1264|回复: 12
收起左侧

为什么1<<17无法得到0x020000?C语言程序

[复制链接]
ID:71233 发表于 2023-8-15 08:05 | 显示全部楼层 |阅读模式
在在keil C51中,想用1<<17来得到0x020000,可是无法得到这样的结果。想得到常数0x020000,只能使用宏定义:#define T17 0x020000
因C水平有限,不知道是什么原因,请各位大佬赐教,谢谢!


回复

使用道具 举报

ID:712097 发表于 2023-8-15 09:01 | 显示全部楼层
从计算结果来看,1<<17=131072=0x020000没问题呀,是不是数据类型定义不对呀,用unsigned long类型试一下。
回复

使用道具 举报

ID:190832 发表于 2023-8-15 09:15 | 显示全部楼层
51是8位单片机,1<<17的1是16位的,左移17位就只剩0了。
回复

使用道具 举报

ID:939553 发表于 2023-8-15 10:54 来自手机 | 显示全部楼层
(unsigned long)1 << 17
回复

使用道具 举报

ID:1073939 发表于 2023-8-15 11:35 | 显示全部楼层
#define T17 (1L<<17)

这是正确的定义
回复

使用道具 举报

ID:1073939 发表于 2023-8-15 11:45 | 显示全部楼层
T17.png

经验证,13行定义不行。
11行 12行定义都可以。11行定义是通用的做法。
回复

使用道具 举报

ID:1053359 发表于 2023-8-15 12:44 | 显示全部楼层
在Keil C51中,使用1 << 17 来得到 0x020000 是行不通的。这是因为在C语言中,1 是一个整型常量,默认是32位的,而在C51中,整型默认是16位的。所以左移17位将会导致溢出。

要得到 0x020000 这个常数,你可以使用宏定义,像你提到的那样:
#define T17 0x020000
通过这种方式,你可以在代码中使用 T17 来代表常数 0x020000。
另外,如果你需要使用 1 << 17 进行移位操作,你可以使用长整型进行计算,然后截取需要的位数。例如:
unsigned long result = 1UL << 17;
unsigned int finalResult = (unsigned int)(result & 0xFFFF);
上述代码中,首先使用 unsigned long 类型接收移位结果,然后再使用 unsigned int 类型接收结果的低16位(0x20000 & 0xFFFF),即 0x0000FFFF。这样你就可以得到想要的结果。
回复

使用道具 举报

ID:883242 发表于 2023-8-15 13:59 | 显示全部楼层
real8799190 发表于 2023-8-15 12:44
在Keil C51中,使用1

你的解释是正确的,但是解决方案并不好,
unsigned long result
这句话就占用了4个字节的RAM空间,MCS-51这个体系太落后了,直接寻址能力只有128 bytes,寸土寸金的地方一下子消耗掉4 bytes太浪费。
改成
#define T17 0x20000UL
最后消耗的是code空间,反正这个空间足够大,多消耗十几个字节都可以忽略不计。
回复

使用道具 举报

ID:71233 发表于 2023-8-15 16:19 | 显示全部楼层
本帖最后由 lmn2005 于 2023-8-15 16:34 编辑

试了这种写法,可以解决问题,谢谢!
回复

使用道具 举报

ID:71233 发表于 2023-8-15 16:21 | 显示全部楼层
chxelc 发表于 2023-8-15 09:01
从计算结果来看,1

有定义过,即
unsigned long i;
i=1<<17;
也无法解决问题
回复

使用道具 举报

ID:71233 发表于 2023-8-15 16:24 | 显示全部楼层
ydatou 发表于 2023-8-15 11:45
经验证,13行定义不行。
11行 12行定义都可以。11行定义是通用的做法。

谢谢!用11行最简单好用!
回复

使用道具 举报

ID:1034262 发表于 2023-8-15 16:56 | 显示全部楼层
C51默认是16位的常数,要指定或强转32位,
1UL << 17
(u32)1 << 17
回复

使用道具 举报

ID:962286 发表于 2023-8-17 10:31 | 显示全部楼层
lmn2005 发表于 2023-8-15 16:21
有定义过,即
unsigned long i;
i=1

它是先计算1<<17,再将结果赋值到变量i,所以还是回到最先的问题来,最终也是错误。要写成:
i = 1;
i <<= 17;
不过如果是常量,就没必要浪费RAM空间了。直接 (1UL << 17)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表