发新帖本帖赏金 2.00元(功能说明)我要提问
返回列表
打印

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

[复制链接]
1566|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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多亿秒总不会溢出了吧?

使用特权

评论回复
5
hzocce|  楼主 | 2015-11-30 16:29 | 只看该作者
diweo 发表于 2015-11-30 15:36
65535不够那就用32位的啰,40多亿秒总不会溢出了吧?

这个太合理,有没有什么办法处理这种溢出的问题的计算。
程序如何表达????

使用特权

评论回复
6
diweo| | 2015-11-30 19:09 | 只看该作者
这里首先假定int是16位的,那么int a; a的范围是-32768~32767;所以上面说的65536其实是不对的。

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

捕获.JPG (86.52 KB )

捕获.JPG

使用特权

评论回复
7
lxyppc| | 2015-12-1 08:43 | 只看该作者
我起步时候是 3秒,停步时间是23秒,那时间就算出来为   23-3=20秒。
为什么不是80秒,不是3620秒,不是十年又20秒
如果起步时间是 58秒,停步时间是6秒,那时间就是60-58+6 = 8秒。
为什么不是68秒
你怎么知道只过了不到一分钟的时间

使用特权

评论回复
8
datouyuan| | 2015-12-1 09:51 | 只看该作者
本帖最后由 datouyuan 于 2015-12-1 09:56 编辑

楼上正解.
要尽量避免溢出.
可通过增加数据范围或者及时减小数据值的方式避免溢出.

使用特权

评论回复
9
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范围之内呀。

使用特权

评论回复
10
hzocce|  楼主 | 2015-12-1 10:56 | 只看该作者
void Time0() interrupt 3
{

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

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

请问这个 怎么实现?

没有理解楼上几位的意思。:$

使用特权

评论回复
11
huarana| | 2015-12-1 11:02 | 只看该作者
避免溢出只能增加数据范围。

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

使用特权

评论回复
12
21ic小管家| | 2015-12-1 11:10 | 只看该作者
此打赏为十大热门第八名,恭喜恭喜~打赏细则详情请戳https://bbs.21ic.com/icview-1219832-1-1.html

使用特权

评论回复
13
qhdjxy| | 2015-12-1 13:06 | 只看该作者
再加个变量sec作为秒的记录不行吗?

使用特权

评论回复
14
hzocce|  楼主 | 2015-12-1 13:33 | 只看该作者
huarana 发表于 2015-12-1 11:02
避免溢出只能增加数据范围。

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

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

有知道的大神帮忙指导下么???

使用特权

评论回复
15
cool_coder| | 2015-12-1 14:41 | 只看该作者
本帖最后由 cool_coder 于 2015-12-1 14:59 编辑

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

    ……
   if(TimeDiff(a,b) > 20){
        ...
    }

使用特权

评论回复
16
cool_coder| | 2015-12-1 15:03 | 只看该作者
或者写得紧凑点:
    c = (b >= a) ? (b - a) : (65536 - a + b);
    if(c > 20){
        ...
    }

使用特权

评论回复
17
hzocce|  楼主 | 2015-12-1 15:55 | 只看该作者
cool_coder 发表于 2015-12-1 15:03
或者写得紧凑点:

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

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

可否再请请教下,语句 ? 语句 : 语句
这个格式的语句 是怎么使用的? 我找不到这样的资料,想学习一下,谢谢了!

使用特权

评论回复
18
cool_coder| | 2015-12-1 22:31 | 只看该作者
hzocce 发表于 2015-12-1 15:55
非常感谢楼上的 解答!
明白了!

c = (条件)?a:b;
等价于
if(条件){
    c = a;
}else{
    c = b;
}

使用特权

评论回复
19
hzocce|  楼主 | 2015-12-7 13:42 | 只看该作者
谢谢!

使用特权

评论回复
发新帖 本帖赏金 2.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

128

主题

562

帖子

4

粉丝