您的位置:首页 > 其它

C指针原理(33)-C指针基础

2013-11-11 17:06 253 查看
取自netbsd中的源码,检查运算溢出,用C语言实现,方法很精妙

/*

 * hide bintime for _STANDALONE because this header is used for hpcboot.exe,

 * which is built with compilers which don't recognize LL suffix.

 * http://mail-index.NetBSD.org/tech-userlevel/2008/02/27/msg000181.html
 */

下面这段使用了LL后缀,要检查一下编译器是否支持,如果支持,则定义_STANDALONE。这样能容纳的时间数更大。

L是long,LL是long long


本博客所有内容是原创,如果转载请注明来源


http://blog.csdn.net/myhaspl/

定义了bintime的结构,以及其加减运算。uint64_t类型的frac是无符号整数,下面要用到这个特性

#if !defined(_STANDALONE)

struct bintime {
time_t
sec;
uint64_t frac;

};

static __inline void

bintime_addx(struct bintime *bt, uint64_t x)

{
uint64_t u;

u = bt->frac;
bt->frac += x;
if (u > bt->frac)
bt->sec++;

}

数据是以补码方式存放在内存中!无符号整数溢出表现为: x + y < x 就表示溢出了.,因此,上面才有

if (u > bt->frac)

bt->sec++;

这样的判断,很巧妙的想法,溢出了就进位。 

下面演示了加法的溢出



因为上面编译器进行编译时,char是有符号的,即signed char。

在C/C++语言中,char变量为一个字节,8位,signed char表示的范围:-128~127【-128在内存中的二进制表示为1000 0000,127在内存中的表示为0111 1111】;unsign char表示的范围:0000 0000~1111 1111,即0~255;

root@myhaspl:~/test/asb# gcc test1.c

root@myhaspl:~/test/asb# ./a.out

-46

-30

110

root@myhaspl:~/test/asb#

很明显,90+120已经溢出了,因为无法表达210这个有符号数,用一个8位的字节。而a+c则正常计算。

下面继续分析。

static __inline void

bintime_add(struct bintime *bt, const struct bintime *bt2)

{
uint64_t u;

u = bt->frac;
bt->frac += bt2->frac;
if (u > bt->frac)
bt->sec++;
bt->sec += bt2->sec;

}

 bintime_add也完成2个时间结构类型的加法,同样通过溢出检查来实现进位。 

下面是2个时间结构类型的减法。

static __inline void

bintime_sub(struct bintime *bt, const struct bintime *bt2)

{
uint64_t u;

u = bt->frac;
bt->frac -= bt2->frac;
if (u < bt->frac)
bt->sec--;
bt->sec -= bt2->sec;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: