免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6140 | 回复: 10
打印 上一主题 下一主题

[C] 计算机到底是怎么做的位运算? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-09-04 12:04 |只看该作者 |倒序浏览
最近发现一个很有意思的现象,比如一个8位数,char什么的,如果不是无符号的,那么最高位就是符号位,如果是负数,最高位就是二进制1,如果和别的高于8位的数做位运算,会把8位以上的位全部变成1,这是有符号数做位运算出错的根本问题所在。但是,我只需要让这个8位数先和0xFF做一下与运算,再和那些高于8位的数做位运算,高于8位的1全部就没了。但是我就产生了一个疑问,首先就是,按照一般的流程顺序这个过程是说不通的,8位数如果只有8位,是在做位运算的时候把高位变了1,那么和0xff先做与运算就是无效的,除非8位数本身不止8位,高于8位上本身已经是1,被0xff与掉。才说得通。但是我总觉得这个过程也有问题

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
2 [报告]
发表于 2013-09-04 12:26 |只看该作者
1。char未必是有符号的
2。类型扩展
     a。char和int作运算,肯定需要先将char扩展到int类型
     b。扩展应该不改变其值,比如 unsigned char 扩展到 int,值应该不变,比如 10000000(128)应该扩展为000……000 10000000 才能保证还是128
          比如 signed char 扩展到 int,值应该不变,比如 01000000(64)应该扩展为000……000 01000000 才能保证还是64;比如10000000(-128)应该扩展为111……111 10000000 才能保证还是-128
3。0xFF 的类型是 unsigned int

以上三点应该解决了你所有的疑问

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
3 [报告]
发表于 2013-09-05 00:27 |只看该作者
0xff  只能说是int吧?
当然, 无论是Int 还uint, 结果都一样。

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
4 [报告]
发表于 2013-09-05 16:38 |只看该作者
folklore 发表于 2013-09-05 00:27
0xff  只能说是int吧?
当然, 无论是Int 还uint, 结果都一样。

还真是int,奇怪呀,我记得谁说过0x开头的默认为无符号类型

论坛徽章:
17
处女座
日期:2013-08-27 09:59:352015亚冠之柏太阳神
日期:2015-07-30 10:16:402015亚冠之萨济拖拉机
日期:2015-07-29 18:58:182015年亚洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥猪
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56双子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
5 [报告]
发表于 2013-09-05 17:06 |只看该作者
回复 1# abcbuzhiming


    位运算时会进行整型类型提升和常用算术转换:
   
 算术转换规则:
 1、如果一个操作数是long double那么另一个操作数也转换为long double
    2、否则,如果一个操作数是double那么另一个操作数也转换为double
 3、否则,如果一个操作数是float那么另一个操作数也转换为float
   4、否则,在两个操作上执行整型类型提升        
 5、然后,如果一个操作数是unsigned long那么另一个操作数也转换为unsigned long
 6、否则,如果一个操作数是long int另一个是unsigned int,如果long int能表示另一个操作数的值那么另一个操作数转换为long int,否则long int转换为unsigned long int。
 7、否则,如果一个操作数是long那么另一个操作数也转换为long
    7、否则,如果一个操作数是unsigned那么另一个操作数也转换为unsigned


   整型类型提升:
 1、char, signed char, unsigned char, short int, or unsigned short int类型如果可以就转为int,否则转为unsigned int.
    2、wchar_t和枚举类型可以转换为int,unsigned int,long,unsigned long。
 2、位域转换为int,如果其值int容不下则转为unsigned int
    3、bool转换为int

论坛徽章:
7
丑牛
日期:2013-08-29 14:14:00辰龙
日期:2013-09-06 12:28:56技术图书徽章
日期:2013-09-21 21:33:44狮子座
日期:2014-04-04 16:00:37水瓶座
日期:2014-07-31 21:53:132022北京冬奥会纪念版徽章
日期:2015-08-07 17:10:572015七夕节徽章
日期:2015-08-21 09:20:10
6 [报告]
发表于 2013-09-06 22:13 |只看该作者
去找本讲数字逻辑电路的书看看,里头应该会讲清楚,加法器,乘法器,位运算器设计。

32位ALU做8位的运算,高位会自动加填充位,至于填充啥不同处理器的做法是不一样的,可以找书去看看。

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
7 [报告]
发表于 2013-09-07 10:33 |只看该作者
5楼说的对。
和提升有关。

但是一般场景下是 被做运算的数和结果是同长度的,这样不管高出的位在中间过程如何变化都不影响结果。
关键在第2步,应该不使用中间结果做运算而是应该强制用第一步的结果做运算才合理。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
8 [报告]
发表于 2013-09-07 14:46 |只看该作者
我就搞不懂  (char)a  <<  (int)b ,结果是 char 还是 int

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
9 [报告]
发表于 2013-09-07 14:56 |只看该作者
群雄逐鹿中原 发表于 2013-09-07 14:46
我就搞不懂  (char)a  <<  (int)b ,结果是 char 还是 int

按C标准,a<<b 这个表达式的类型只取决于a的类型,同时,任何类型做元素,级别低于int的都需要提升到int类型。
也就是 a<<b 表达式的类型是 a的类型 和 int类型 中最大的那个
对于 (char)a  <<  (int)b 而言,结果类型就是 int

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
10 [报告]
发表于 2013-09-07 15:13 |只看该作者
看了一下C标准,顺便记下来

a << b
a和b都作整型提升,a<<b结果类型是a整型提升后的类型。
如果b为负值,或大于等于『a整型提升后的类型 的宽度』,行为未定义。

左移b个bit位置,空位补0
如果a为无符号类型,结果是 a*(2的b次方) 再模除结果类型的最大值
如果a为有符号类型,且结果类型能容纳 a*(2的b次方),那么就是 a*(2的b次方),否则行为未定义。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP