2变量差值计算如何实现?

[复制链接]
 楼主| hzocce 发表于 2015-11-30 15:06 | 显示全部楼层 |阅读模式
本帖最后由 hzocce 于 2015-12-1 10:52 编辑

打个比方,时间从1秒,2秒,3秒,4秒开始跑。。。。
我起步时候是 3秒,停步时间是23秒,那时间就算出来为   23-3=20秒。
如果起步时间是 58秒,停步时间是6秒,那时间就是60-58+6 = 8秒。

unsigned int a,unsigned int b;
为起步时间,b为停步时间。
要计算 b和a之间的差值,
问题就来了,当变量在没有溢出之前,停步时间减去起步时间就是相差时间。
但如果溢出了,则为 65536-a+b 的情况。

我现在就是用这个时间差做 一个前提条件,
文字表达意思是:
如果时间差大于20秒,则执行后面的语句。
这个怎么表达?

打赏榜单

21ic小管家 打赏了 2.00 元 2015-12-01

 楼主| hzocce 发表于 2015-11-30 15:11 | 显示全部楼层
本帖最后由 hzocce 于 2015-11-30 15:14 编辑

能整编成  if    (;;) ||  (;;)    这个类型么?
 楼主| hzocce 发表于 2015-11-30 15:30 | 显示全部楼层
if(b>a) (b-a)>20     或者   if (b<a)(65536-a+b)>30
只要差值大于 20 。
diweo 发表于 2015-11-30 15:36 | 显示全部楼层
65535不够那就用32位的啰,40多亿秒总不会溢出了吧?
 楼主| hzocce 发表于 2015-11-30 16:29 | 显示全部楼层
diweo 发表于 2015-11-30 15:36
65535不够那就用32位的啰,40多亿秒总不会溢出了吧?

这个太合理,有没有什么办法处理这种溢出的问题的计算。
程序如何表达????
diweo 发表于 2015-11-30 19:09 | 显示全部楼层
这里首先假定int是16位的,那么int a; a的范围是-32768~32767;所以上面说的65536其实是不对的。

要处理你说的问题。可以这样定义unsigned int a,b;
这样b-a就是它们的差值,即使a还没溢出而b已经溢出也没有关系。因为a很接近溢出的时候,其实相当于负数接近0的时候。

本帖子中包含更多资源

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

×
lxyppc 发表于 2015-12-1 08:43 来自手机 | 显示全部楼层
我起步时候是 3秒,停步时间是23秒,那时间就算出来为   23-3=20秒。
为什么不是80秒,不是3620秒,不是十年又20秒
如果起步时间是 58秒,停步时间是6秒,那时间就是60-58+6 = 8秒。
为什么不是68秒
你怎么知道只过了不到一分钟的时间
datouyuan 发表于 2015-12-1 09:51 | 显示全部楼层
本帖最后由 datouyuan 于 2015-12-1 09:56 编辑

楼上正解.
要尽量避免溢出.
可通过增加数据范围或者及时减小数据值的方式避免溢出.
diweo 发表于 2015-12-1 10:03 | 显示全部楼层
本帖最后由 diweo 于 2015-12-1 10:13 编辑
lxyppc 发表于 2015-12-1 08:43
我起步时候是 3秒,停步时间是23秒,那时间就算出来为   23-3=20秒。
为什么不是80秒,不是3620秒,不是十 ...

假设有个变量sec来表示秒数,那么每过1秒就sec++,它到60也好120也好,不需要限制在0~60范围之内呀。
 楼主| hzocce 发表于 2015-12-1 10:56 | 显示全部楼层
void Time0() interrupt 3
{

        if(Fifty_ms++==20)
        {
                Fifty_ms=0;
                Second++;
        };           //自加一次为50ms
}

我的定时器是这样的, 全局变量 unsigned int Second ,
通过计算原来Second初值,跟后面Second值来计算 时间差。

请问这个 怎么实现?

没有理解楼上几位的意思。:$
huarana 发表于 2015-12-1 11:02 | 显示全部楼层
避免溢出只能增加数据范围。

sec不能无限增大去吧,达到某个条件就要重新来过才行的啊
21ic小管家 发表于 2015-12-1 11:10 | 显示全部楼层
此打赏为十大热门第八名,恭喜恭喜~打赏细则详情请戳https://bbs.21ic.com/icview-1219832-1-1.html
qhdjxy 发表于 2015-12-1 13:06 | 显示全部楼层
再加个变量sec作为秒的记录不行吗?
 楼主| hzocce 发表于 2015-12-1 13:33 | 显示全部楼层
huarana 发表于 2015-12-1 11:02
避免溢出只能增加数据范围。

sec不能无限增大去吧,达到某个条件就要重新来过才行的啊 ...

达到 65535的时候,Second会清零,可是我这个办法,怎么计算差值?

有知道的大神帮忙指导下么???
cool_coder 发表于 2015-12-1 14:41 | 显示全部楼层
本帖最后由 cool_coder 于 2015-12-1 14:59 编辑

既然LZ用了16位的变量,只判断20秒左右的差值,那么判断间隔肯定不会大于65536秒的,对吧?所关心的溢出问题,也应该仅出现在65535附近的一小段时间里。所以,不用担心几天,几年的问题,只关心附近这几分钟就可以了。
  1. uint16_t TimeDiff(uint16_t tmStart, uint16_t tmStop)
  2. {
  3.     if(tmStop >= tmStart){
  4.         return (tmStop - tmStart);
  5.     }else{
  6.         return (65536 - tmStart + tmStop);
  7.     }
  8. }

  9.     ……
  10.    if(TimeDiff(a,b) > 20){
  11.         ...
  12.     }
cool_coder 发表于 2015-12-1 15:03 | 显示全部楼层
或者写得紧凑点:
  1.     c = (b >= a) ? (b - a) : (65536 - a + b);
  2.     if(c > 20){
  3.         ...
  4.     }

 楼主| hzocce 发表于 2015-12-1 15:55 | 显示全部楼层
cool_coder 发表于 2015-12-1 15:03
或者写得紧凑点:

非常感谢楼上的 解答!
明白了!

对于
c = (b >= a) ? (b - a) : (65536 - a + b);

可否再请请教下,语句 ? 语句 : 语句
这个格式的语句 是怎么使用的? 我找不到这样的资料,想学习一下,谢谢了!
cool_coder 发表于 2015-12-1 22:31 | 显示全部楼层
hzocce 发表于 2015-12-1 15:55
非常感谢楼上的 解答!
明白了!

c = (条件)?a:b;
等价于
if(条件){
    c = a;
}else{
    c = b;
}
 楼主| hzocce 发表于 2015-12-7 13:42 | 显示全部楼层
谢谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

617

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部