独闷闷网

 找回密码
 立即注册
搜索
查看: 10376|回复: 0
打印 上一主题 下一主题
收起左侧

[原创] 《鸿哥发现》:如何解决乘法运算的中间过程超过32位变量范围溢出错误的问题。

[复制链接]
跳转到指定楼层
楼主
发表于 2016-11-6 11:42:22 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
★坚鸿-深圳:
      大家好,我是鸿哥,现在是本群特别节目《鸿哥发现》。节目现在开始。
      我以前做单片机自由职业者的时候,每次接到项目,有一个地方我都小心翼翼,生怕出错,这个地方很敏感,它是什么呢?就是怕乘法溢出。最大的32位变量,毕竟数值范围有限,而我每次又把小数点先放大成整数后再计算,更加容易溢出超个32位的最大变量数值,印象最深刻的一次某个项目,因为乘法溢出的问题,逼得我自己用大数组来做乘法的算法处理,很麻烦。但是,今天,我要跟过去说拜拜了,因为,今天我又遇到这个问题,但是这次,我没有用那个大数组处理的思路,而是有了更加简单的处理思路,这一次,让我体会到了什么叫高峰体验,原来可以这么爽。我今天遇到的问题如下:
       我用的是stm32F429单片机,一开始的代码是这样子的:
  1. u32 a,b,d;
  2. d=a*b/10000;
复制代码
      但是,上述代码,当a等于1000000,b等于5000,运算结果是出乎意外,居然不是500000!出错了。我仔细一分析,又是溢出的问题,因为中间第一步a*b就等于5000000000,超过32位变量类型的范围了,所以出错,正当我纳闷的时候,我就想起了曾经听别人传说过stm32的单片机有一个64位的unsigned long long类型,比u32还大范围的,是64位。于是,更改了试试,结果,奇迹出现了,成功了。我是这样更改的:

  1. u32 a,b,d;
  2. d=((unsigned long long)a*(unsigned long long)b)/10000;//括号的(unsigned long long)表示类型强制转换成64位再计算
复制代码

       最后d的结果就是正确的500000.通过这件事,我发现stm32真的比51爽,因为我试了试在C51编辑器上输入unsigned long long变量会出错。就是不知道其它还有哪些单片机能支持64位的变量。这个64位的数据类型在乘除法的运算中真的太重要太实用了,假如所有的单片机都支持这个功能该多好。
乐于分享,勇于质疑!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|独闷闷网 ( 粤ICP备12007667号-2 )

GMT+8, 2024-12-2 02:35 , Processed in 0.721583 second(s), 18 queries .

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