本文目录一览:
我想问一个简单的C语言问题,就是关于浮点数的陷阱。
这是因为你累加的步长是0.1,如果你加的是1.0就可以正常退出循环。
为什么步长是0.1就不行,因为double,float这类浮点数是二进制浮点数。
它的大于一部分的值,是精确的,因为大与一的值是整数,是2^0 2^1 2^2 这样二的幂累加而得的。
小于一的部分,就不一定了,它们还是由二的幂累加,从2^-1 2^-2 2^-3也就是1/2, 1/4, 1/8这样累加起来的,这样对于有些10进制的小数,是无法精确表达的,只能近似表达。
比如0.2=1/5 这个数用2的负数次冥来表示是不行的
(二的负数次冥为1/2, 1/4, 1/8
0.2=1/5 约等于51/256 = 1/256 + 25/128 = 1/256 + 1/128 + 3/16 = 1/256 + 1/128 + 1/16 + 1/8=
0 × (1) + 0 × (1/2) + 0×(1/4) + 1 ×(1/8) + 1× (1/16) + 0 ×(1/32) + 0 ×(1/64) + 1 × (1/128) +1 × (1/256) = 0.00110011 这就是0.2的二进制小数表示。
由此可见,只要小数的值不能化为二的负冥的整数倍(这种情况很多),那么二进制表示的小数,都只能是近似值。
既然是近似值你累加0.1想得到10.0的精确值自然不可能,判断i != 10基本都会失败,除非你累加的是精确的浮点数,比如1.0,或者0.125之类,整数个步长刚好可以达到你的判断条件----10的。
所以一般这种判断,都是用i = 10这样。
求C语言大神看3道有陷阱的入门编程题?
这是C语言中的“右移运算符”。一般情况下,他是按位操作。
特点:1.双目运算符,就像+、-、*、/一样,格式为(数1)(数2)
2.数1是被操作数,如被减数、被除数等;数2是右移位数。
3.优先级低,结合性:从左向右运算
如:81=?表示将被移数向右移动1位
如何操作?
1.化十进制数为(注意了)对应的二进制数,对应指格式对应
2.通通右移,不足补0
3.化为十进制数
举例:short int a=8;a=a1;
1.a=0 000 1000
2.右移一位后:a= 0 000 100
3.补0:a=0 000 0100
4.化为十进制数:a=4
举例:int a=8;a=a1;
1.a=0 000 0000 0000 1000
2.右移一位后:a= 0 000 0000 0000 100
3.补0:a=0 000 0000 0000 0100
4.化为十进制数:a=4
一道有陷阱的C语言问题,请各位大虾们看看
改成下面的代码,注意计算sum的地方
#includestdio.h
int main()
{
int n,m,i;
double sum=0.0;
scanf("%d %d",n,m);
if(nm||n=0||n1000000||m=0||m1000000)
return 0;
for(i=0;i=m-n;i++)
{
double t = n+i;
sum+=1.0/(t*t);
}
printf("%.5lf",sum);
return 0;
}
原来你用的:((n+i)*(n+i))会溢出,65536*65536 = 4294967296超过int能表示的最大值