⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c语言中的位运算 - 嵌入式系统、软件、驱动 - 电子工程博客 - powered by supesite.htm

📁 最全的介绍C语言结构体的使用方法和使用技巧!
💻 HTM
📖 第 1 页 / 共 2 页
字号:
      129 = 10000001<BR>A2A3.....An就是尾数位,不足23位后补0<BR>所以5.5 = 
      01000000101000000000000000000000 = 40A00000<BR>所以,对浮点数*2、/2只要对8位符号位+、- 
      即可,但不是左移、右移 <BR><BR>关于unsigned int 和 int 
      的在位运算上的不同,下面有个CU上的例子描述的很清楚:<BR><BR>[问题]:这个函数有什么问题吗?<BR><BR>/////////////////////////////////////////////////<BR>/**<BR>* 
      本函数将两个16比特位的值连结成为一个32比特位的值。<BR>* 参数:sHighBits 高16位<BR>* sLowBits 低16位<BR>* 
      返回:32位值<BR>**/<BR>long CatenateBits16(short sHighBits, short 
      sLowBits)<BR>{<BR>long lResult = 0; /* 32位值的临时变量*/<BR><BR>/* 
      将第一个16位值放入32位值的高16位 */<BR>lResult = sHighBits;<BR>lResult &lt;&lt;= 
      16;<BR><BR>/* 清除32位值的低16位 */<BR>lResult &amp;= 0xFFFF0000;<BR><BR>/* 
      将第二个16位值放入32位值的低16位 */<BR>lResult |= (long)sLowBits;<BR><BR>return 
      lResult;<BR>}<BR>/////////////////////////////////////////////////<BR><BR><BR>[问题的发现]:<BR><BR>我们先看如下测试代码:<BR><BR>/////////////////////////////////////////////////<BR>int 
      main()<BR>{<BR>short sHighBits1 = 0x7fff;<BR>short sHighBits2 = 
      0x8f12;<BR>unsigned short usHighBits3 = 0xff12;<BR>short sLowBits1 = 
      0x7bcd; <BR>long lResult = 0;<BR><BR>printf("[sHighBits1 + sLowBits1] 
      ";<BR><BR>lResult = CatenateBits16(sHighBits1, 
      sLowBits1);<BR>printf("lResult = %08x ", lResult, lResult);<BR><BR>lResult 
      = CatenateBits16(sHighBits2, sLowBits1);<BR>printf("lResult = %08x ", 
      lResult, lResult);<BR><BR>lResult = CatenateBits16(usHighBits3, 
      sLowBits1);<BR>printf("lResult = %08x ", lResult, lResult); 
      <BR>}<BR>/////////////////////////////////////////////////<BR><BR>运行结果为:<BR><BR>[sHighBits1 
      + sLowBits1]<BR>lResult = 7fff7bcd<BR>lResult = 8f127bcd<BR>lResult = 
      ff127bcd<BR><BR>嗯,运行很正确嘛……于是我们就放心的在自己的程序中使用起这个函数来了。<BR><BR>可是忽然有一天,我们的一个程序无论如何结果都不对!经过n个小时的检查和调试,最后终于追踪到……CatenateBits16() 
      !?它的返回值居然是错的!!<BR><BR>“郁闷!”你说,“这个函数怎么会有问题呢!?”<BR><BR>可是,更郁闷的还在后头呢,因为你把程序中的输入量作为参数,在一个简单的main()里面单步调试:<BR><BR>/////////////////////////////////////////////////<BR>int 
      main()<BR>{<BR>short sHighBits1 = 0x7FFF;<BR>short sHighBits2 = 
      0x8F12;<BR>unsigned short usHighBits3 = 0x8F12;<BR><BR>short sLowBits1 = 
      0x7BCD; //你实际使用的参数<BR>short sLowBits2 = 0x8BCD; //你实际使用的参数<BR><BR>long 
      lResult = 0;<BR><BR>printf("[sHighBits1 + sLowBits1] ";<BR><BR>lResult = 
      CatenateBits16(sHighBits1, sLowBits1);<BR>printf("lResult = %08x ", 
      lResult, lResult);<BR><BR>lResult = CatenateBits16(sHighBits2, 
      sLowBits1);<BR>printf("lResult = %08x ", lResult, lResult);<BR><BR>lResult 
      = CatenateBits16(usHighBits3, sLowBits1);<BR>printf("lResult = %08x ", 
      lResult, lResult); <BR><BR>printf(" [sHighBits1 + sLowBits2] 
      ";<BR><BR>lResult = CatenateBits16(sHighBits1, 
      sLowBits2);<BR>printf("lResult = %08x ", lResult, lResult);<BR><BR>lResult 
      = CatenateBits16(sHighBits2, sLowBits2);<BR>printf("lResult = %08x ", 
      lResult, lResult);<BR><BR>lResult = CatenateBits16(usHighBits3, 
      sLowBits2);<BR>printf("lResult = %08x ", lResult, lResult);<BR><BR>return 
      0;<BR>}<BR>/////////////////////////////////////////////////<BR><BR>发现结果竟然是:<BR><BR>[sHighBits1 
      + sLowBits1]<BR>lResult = 7fff7bcd<BR>lResult = 8f127bcd<BR>lResult = 
      8f127bcd<BR><BR>[sHighBits1 + sLowBits2]<BR>lResult = ffff8bcd 
      //oops!<BR>lResult = ffff8bcd //oops!<BR>lResult = ffff8bcd 
      //oops!<BR><BR>前一次还好好的,后一次就ffff了?X档案?<BR><BR><BR>[X档案的真相]:<BR><BR>注意那两个我们用来当作低16位值的sLowBits1和sLowBits2。<BR><BR>已知:<BR>使用 
      sLowBits1 = 0x7bcd 时,函数返回正确的值;<BR>使用 sLowBits2 = 0x8bcd 
      时,函数中发生X档案。<BR><BR>那么,sLowBits1与sLowBits2有什么区别?<BR><BR>注意了,sLowBits1和sLowBits2都是short型(而不是unsigned 
      short),所以在这里,sLowBits1代表一个正数值,而sLowBits2却代表了一个负数值(因为8即是二进制1000,sLowBits2最高位是1)。<BR><BR>再看CatenateBits16()函数:<BR><BR>/////////////////////////////////////////////////<BR>long 
      CatenateBits16(short sHighBits, short sLowBits)<BR>{<BR>long lResult = 0; 
      /* 32位值的临时变量*/<BR><BR>/* 将第一个16位值放入32位值的高16位 */<BR>lResult = 
      sHighBits;<BR>lResult &lt;&lt;= 16;<BR><BR>/* 清除32位值的低16位 */<BR>lResult 
      &amp;= 0xFFFF0000;<BR><BR>/* 将第二个16位值放入32位值的低16位 */<BR>lResult |= 
      (long)sLowBits; //注意这一句!!!!<BR><BR>return 
      lResult;<BR>}<BR>/////////////////////////////////////////////////<BR><BR>如果我们在函数中用<BR><BR>printf("sLowBits 
      = %04x ", sLowBits);<BR><BR>打印传入的sLowBits值,会发现<BR><BR>sLowBits = 0x7bcd 
      时,打印结果为<BR><BR>sLowBits = 7bcd<BR><BR>而sLowBits = 
      0x8bcd时,打印结果为<BR><BR>sLowBits = 
      ffff8bcd<BR><BR>是的,即使用%04x也打印出8位十六进制。<BR><BR>因此,我们看出来了:<BR><BR>当sLowBits = 
      0x8bcd时,函数中 "lResult |= (long)sLowBits;" 
      这一句执行,会先将sLowBits转换为<BR><BR>0xffff8bcd<BR><BR>再与lResult做或运算。由于现在lResult的值为 
      0xXXXX0000 
      (其中XXXX是任何值),所以显然,无论sHighBits是什么值,最后结果都会是<BR><BR>0xffff8bcd<BR><BR>而当sLowBits 
      = 0x7bcd时,函数中 "lResult |= (long)sLowBits;" 
      这一句执行,会先将sLowBits转换为<BR><BR>0x00007bcd<BR><BR>再与lResult做或运算。这样做或运算出来的结果当然就是对的。<BR><BR>也就是说,CatenateBits16()在sLowBits的最高位为0的时候表现正常,而在最高位为1的时候出现偏差。<BR><BR>[教训:在某些情况下作位运算和位处理的时候,考虑使用无符号数值——因为这个时候往往不需要处理符号。即使你需要的有符号的数值,那么也应该考虑自行在调用CatenateBits16()前后做转换——毕竟在位处理中,有符号数值相当诡异!]<BR><BR>下面这个CatenateBits16()版本应该会好一些:<BR><BR>/////////////////////////////////////////////////<BR>unsigned 
      long CatenateBits16(unsigned short sHighBits, unsigned short 
      sLowBits)<BR>{<BR>long lResult = 0;<BR><BR>/* 将第一个16位值放入32位值的高16位 
      */<BR>lResult = sHighBits;<BR>lResult &lt;&lt;= 16;<BR><BR>/* 清除32位值的低16位 
      */<BR>lResult &amp;= 0xFFFF0000;<BR><BR>/* 将第二个16位值放入32位值的低16位 
      */<BR>lResult |= (long)sLowBits &amp; 0x0000FFFF;<BR><BR>return 
      lResult;<BR>}<BR>/////////////////////////////////////////////////<BR><BR>注意其中的 
      "lResult |= (long)sLowBits &amp; 
      0x0000FFFF;"。事实上,现在即使我们把CatenateBits16()函数的参数(特别是sLowBits)声明为short,结果也会是对的。<BR><BR>如果有一天你把一只兔子扔给一只老虎,老虎把兔子吃了,第二天把一只老鼠扔给它,它又吃了,那么说明第一天你看错了:它本来就是一只猫。</FONT><BR><!-- 正文结束 --></P></TD></TR>
  <TR>
    <TD><BR>全文结束 </TD></TR></TBODY></TABLE></FONT><BR></DIV></DIV>
<DIV id=comment>
<H3><A href="http://bbs.ee365.cn/post.php?action=reply&amp;tid=20716" 
target=_blank>我也来说两句</A> <A style="MARGIN-RIGHT: 0.5em" 
href="http://bbs.ee365.cn/viewthread.php?tid=20716" target=_blank>查看全部评论</A> 
<STRONG>相关评论</STRONG> </H3>
<UL class=messagelist></UL>
<DIV class=pages>
<TABLE class=xspace-page summary="">
  <TBODY>
  <TR>
    <TD><A href="http://bbs.ee365.cn/viewthread.php?tid=20716" 
      target=_blank>查看全部评论</A></TD>
    <TD><A href="http://bbs.ee365.cn/post.php?action=reply&amp;tid=20716" 
      target=_blank>我也来说两句</A></TD></TR></TBODY></TABLE></DIV></DIV></DIV></DIV>
<SCRIPT language=javascript type=text/javascript>
<!--
addImgLink("articlebody");
addImgLink("commentlist");
//-->
</SCRIPT>

<DIV class=sidebar>
<DIV id=hotthread>
<H3>近期热点主题</H3>
<UL>
  <LI><A title=求助!!lwip移植后PING不通,请高手帮忙看一下,问题可能出在哪里? 
  href="http://space.ee365.cn/?action-viewthread-tid-28189" 
  target=_blank>求助!!lwip移植后PING不通,请高手帮忙看一下,问题可能出在哪里?</A> </LI>
  <LI><A title=令人瞠目的USB比基尼泳装,太有创意了! 
  href="http://space.ee365.cn/?action-viewthread-tid-28174" 
  target=_blank>令人瞠目的USB比基尼泳装,太有创意了!</A> </LI>
  <LI><A title="嵌入式操作系统uC/OS uClinux的比较" 
  href="http://space.ee365.cn/?action-viewthread-tid-28171" 
  target=_blank>嵌入式操作系统uC/OS uClinux的比较</A> </LI>
  <LI><A title=IE浏览器的插件处理(原创) 
  href="http://space.ee365.cn/?action-viewthread-tid-28127" 
  target=_blank>IE浏览器的插件处理(原创)</A> </LI>
  <LI><A title=RFID工作频率指南和典型应用 
  href="http://space.ee365.cn/?action-viewthread-tid-28173" 
  target=_blank>RFID工作频率指南和典型应用</A> </LI>
  <LI><A title=工控软件的抗干扰设计 
  href="http://space.ee365.cn/?action-viewthread-tid-28176" 
  target=_blank>工控软件的抗干扰设计</A> </LI>
  <LI><A title=请问lwIP的源码是在哪里下载的啊 
  href="http://space.ee365.cn/?action-viewthread-tid-28192" 
  target=_blank>请问lwIP的源码是在哪里下载的啊</A> </LI>
  <LI><A title="RFID 测试技术分析" 
  href="http://space.ee365.cn/?action-viewthread-tid-28172" target=_blank>RFID 
  测试技术分析</A> </LI>
  <LI><A title=“ST-Embest杯”颁奖大会暨Cortex技术研讨会(送iPOD) 
  href="http://space.ee365.cn/?action-viewthread-tid-28190" 
  target=_blank>“ST-Embest杯”颁奖大会暨Cortex技术研讨会(送iPOD)</A> </LI>
  <LI><A title=有关遥控编码通讯控制的一些心得 
  href="http://space.ee365.cn/?action-viewthread-tid-28212" 
  target=_blank>有关遥控编码通讯控制的一些心得</A> <!--版块最新主题--></LI></UL></DIV>
<DIV id=newthreads>
<H3>最新主题</H3>
<UL>
  <LI><A title=通广集团与河北省签定合同发展数字电视 
  href="http://space.ee365.cn/?action-viewthread-tid-28229" 
  target=_blank>通广集团与河北省签定合</A> </LI>
  <LI><A title=您的论文发表了吗??? 
  href="http://space.ee365.cn/?action-viewthread-tid-28228" 
  target=_blank>您的论文发表了吗???</A> </LI>
  <LI><A title=请教关于sys_timeout()超时检测的问题 
  href="http://space.ee365.cn/?action-viewthread-tid-28223" 
  target=_blank>请教关于sys_timeout()超</A> </LI>
  <LI><A title="[原创]国家级科技期刊   征集论文" 
  href="http://space.ee365.cn/?action-viewthread-tid-28217" 
  target=_blank>[原创]国家级科技期刊 </A></LI>
  <LI><A title=有关遥控编码通讯控制的一些心得 
  href="http://space.ee365.cn/?action-viewthread-tid-28212" 
  target=_blank>有关遥控编码通讯控制的</A> </LI>
  <LI><A title=请问lwIP的源码是在哪里下载的啊 
  href="http://space.ee365.cn/?action-viewthread-tid-28192" 
  target=_blank>请问lwIP的源码是在哪里</A> </LI>
  <LI><A title=“ST-Embest杯”颁奖大会暨Cortex技术研讨会(送iPOD) 
  href="http://space.ee365.cn/?action-viewthread-tid-28190" 
  target=_blank>“ST-Embest杯”颁奖大会</A> </LI>
  <LI><A title=求助!!lwip移植后PING不通,请高手帮忙看一下,问题可能出在哪里? 
  href="http://space.ee365.cn/?action-viewthread-tid-28189" 
  target=_blank>求助!!lwip移植后PING</A> </LI>
  <LI><A title=工控软件的抗干扰设计 
  href="http://space.ee365.cn/?action-viewthread-tid-28176" 
  target=_blank>工控软件的抗干扰设计</A> </LI>
  <LI><A title=令人瞠目的USB比基尼泳装,太有创意了! 
  href="http://space.ee365.cn/?action-viewthread-tid-28174" 
  target=_blank>令人瞠目的USB比基尼泳装</A> <!--论坛最新主题列表--></LI></UL></DIV></DIV>
<DIV class=hackbox></DIV></DIV><!-- Footer -->
<DIV id=footer>
<P><A href="http://space.ee365.cn/" target=_self>电子工程博客</A> | <A 
href="http://space.ee365.cn/?action_site_type_panel" target=_self>快捷面板</A> | <A 
href="http://space.ee365.cn/?action_site_type_map" target=_self>站点地图</A> | <A 
href="http://space.ee365.cn/?action_site_type_link" target=_self>友情链接</A> | <A 
href="mailto:gaofeng@ee365.cn" target=_self>联系我们</A></P>
<P>Powered by <A href="http://www.supesite.com/" 
target=_blank><STRONG>SupeSite</STRONG></A> <EM>5.5</EM> &copy; 2001-2006 <A 
href="http://www.comsenz.com/" target=_blank>Comsenz Inc.</A> </P>
<P></P></DIV><!-- /Footer --></DIV></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -