《 C 语言的一些“骚操作”及其深层理解》之关于数据的直接操作和浮点的四舍五入与比较
扫描二维码
随时随地手机看文章
关于数据的直接操作
直接操作数据?我们来举个例子:取一个整型数的相反数。一般的实现方法是这样的:
int a=10;
int b=-a; //-1*a;
这样的操作可能会涉及到一次乘法运算,花费更多的时间。当我们了解了整型数的实质,就可以这样来作:
int a=10;
int b=(~a)+1;
这也许还不足以说明问题,那我们再来看一个例子:取一个浮点数的相反数。似乎只能这样来作:
float a=3.14;
float b=a*-1.0;
其实我们可以这样来作:
float a=3.14;
float b;
((unsigned char *)&a)[3]^=0X80;
b=a;
没错,我们可以直接修改浮点在内存中的高字节的符号位。这比乘以-1.0的方法要高效的多。
当然,这些操作都需要你对C语言中的指针有炉火纯青的掌握。
浮点的四舍五入与比较
我们先说第一个问题:如何实现浮点的四舍五入?很多人遇到过这个问题,其实很简单,只需要把浮点+0.5然后取整即可。
OK,第二个问题:浮点的比较。这个问题还有必要好好说一下。首先我们要知道,C语言中的判等,即==,是一中强匹配的行为。也就是,比较双方必须每一个位都完全一样,才认定它们相等。这对于整型来说,是可以的。但是float类型则不适用,因为两个看似相等的浮点数,其实它们的内存表达不能保证每一个位都完全一样。
这个时候,我们作一个约定:两个浮点只要它们之差m足够小,则认为它们相等,m一般取10e-6。也就是说,只要两个浮点小数点后6位相同,则认为它们相等。也正是因为这个约定,很多C编译器把float的精度设定为小数点后7位,比如ARMCC(MDK的编译器)。
float a,b;
if(a==b) ... //错误
if(fabs(a-b)<=0.000001) ...//正确