有一篇讲面试台湾
Realtek
公司嵌入式开发的题目。看的时候突然想起优化一下,顺便讨论下嵌入式中
'%'
的优化替换。
题目:
1)
写一个函数计算当参数为
n(n
很大
)
时的值
1-2+3-4+5-6+7……+n
文中考官给的答案:
long fn(long n)
{
if(n<=0)
{
printf("error: n must > 0");
exit(1);
}
if(0==n%2)
return (n/2)*(-1);
else
return (n/2)*(-1)+n;
}
{
if(n<=0)
{
printf("error: n must > 0");
exit(1);
}
if(0==n%2)
return (n/2)*(-1);
else
return (n/2)*(-1)+n;
}
首先,我想到这条语句:
if(0==n%2)
是想测试
n
是奇、偶数。思路很简单,看这个整数是不是可以整除
2
。但
%
运算相对来说比较占
cpu
周期,效率不高。因此我想从这里下手。一个数如果是偶数,除以
2
的结果是偶数;如果是奇数,除以
2
的结果是有小数的。我的原理就是,奇数除以
2
后的结果再取整,看看取整后是否和商相等。或者,看奇数除以
2
的结果取整后再和奇数减去
1
再除以
2
的结果一样否。如果一样,该数就是奇数;否则,该数就是偶数。比如
5/2==(5-1)/2
。说到这里就要说下
c
语言中取整的方式和
'/'
运算。以下摘自问专家:
C
语言有以下几种取整方法:
1 、直接赋值给整数变量。如:
int i = 2.5; 或 i = (int) 2.5;
这种方法采用的是舍去小数部分,可以用于你的问题。
2 、 C/C++ 中的整数除法运算符 “/” 本身就有取整功能 (int / int) ,而下面介绍的取整函数返回值是 double 。整数除法对正数的取整是舍去小数部分,可以用于你的问题。但是整数除法对负数的取整结果和使用的 C 编译器有关。
3 、使用 floor 函数。 floor(x) 返回的是小于或等于 x 的最大整数。如:
floor(2.5) = 2
floor(-2.5) = -3
4 、使用 ceil 函数。 ceil(x) 返回的是大于 x 的最小整数。如:
ceil(2.5) = 3
ceil(-2.5) = -2
floor() 是向负无穷大舍入, floor(-2.5) = -3 ; ceil() 是向正无穷大舍入, ceil(-2.5) = -2 。 floor 函数可以用于你的问题。
hyh 的意见:
int x,a,b,c,d;
a=x/1000;
b=x%1000/100;
c=x%100/10;
d=x%10;
其中 floor 和 ceil 两个函数在 VC++ 中也可以使用,但使用时需要包含 math.h 文件。可以在程序的开始添加如下代码: #include <math.h>
1 、直接赋值给整数变量。如:
int i = 2.5; 或 i = (int) 2.5;
这种方法采用的是舍去小数部分,可以用于你的问题。
2 、 C/C++ 中的整数除法运算符 “/” 本身就有取整功能 (int / int) ,而下面介绍的取整函数返回值是 double 。整数除法对正数的取整是舍去小数部分,可以用于你的问题。但是整数除法对负数的取整结果和使用的 C 编译器有关。
3 、使用 floor 函数。 floor(x) 返回的是小于或等于 x 的最大整数。如:
floor(2.5) = 2
floor(-2.5) = -3
4 、使用 ceil 函数。 ceil(x) 返回的是大于 x 的最小整数。如:
ceil(2.5) = 3
ceil(-2.5) = -2
floor() 是向负无穷大舍入, floor(-2.5) = -3 ; ceil() 是向正无穷大舍入, ceil(-2.5) = -2 。 floor 函数可以用于你的问题。
hyh 的意见:
int x,a,b,c,d;
a=x/1000;
b=x%1000/100;
c=x%100/10;
d=x%10;
其中 floor 和 ceil 两个函数在 VC++ 中也可以使用,但使用时需要包含 math.h 文件。可以在程序的开始添加如下代码: #include <math.h>
所以原来的
if(0==n%2)
return (n/2)*(-1);
else
return (n/2)*(-1)+n;
return (n/2)*(-1);
else
return (n/2)*(-1)+n;
可以改为: