本文章解决的问题是:整形计算赋值给浮点数变量时,浮点变量数值看似异常的问题。问题很基础,适合给同样刚刚开始学习C语言的编程小白参考,且主要作用是希望大家引以为戒,不要犯和作者一样的错误。
在做题目的过程中发现关于double类型的一个问题:
原题目是:由用户输入项数,计算如下两个无穷级数:
?原代码如下:
//练习题6.16.12.c -- 无穷级数
#include<stdio.h>
int power1(int n);
int main(void)
{
double s1 = 0.0,s2 = 0.0,a = 1.0;
int i = 0,t;
long long n;
printf("s1=1+1/2+1/3+1/4...\n");
printf("s2=1-1/2+1/3-1/4...\n");
printf("请输入计算项数,以计算以上两个无穷级数(结束输入q):");
t = scanf("%LLd",&n);
while(t == 1)
{
for(;i++ < n;a = 1 / (i + 1))
{
s1 += a;
s2 += power1(i)*a;
}
printf("s1前%LLd项和为:%lf,s2前%d项和为:%lf\n\n",n,s1,n,s2);
printf("s1=1+1/2+1/3+1/4...\n");
printf("s2=1-1/2+1/3-1/4...\n");
printf("请输入计算项数,以计算以上两个无穷级数(结束输入q):");
t = scanf("%LLd",&n);
i = 0,s1 = 0.0,s2= 0.0,a = 1.0;
}
printf("Done!");
return 0;
}
int power1(int n)
{
int a = -1;
while(n-- > 0)
a = a * (-1);
return a;
}
可是无论输入的n值为几,结果都始终为:s1=1,s2=1
?几经查找后,才发现是a的值有问题,又是几经查找后,终于发现原因:整数运算中,/运算会产生"截断"(truncation),简而言之就是暴力舍弃除法结果的小数部分(非四舍五入),截断发生在除法结束的瞬间,无法在整数除法外添加强制类型转换(如(double))进行修正,例:
//测试.c
#include<stdio.h>
void main(void)
{
double a,b,c,d,e;
a = (double)1 / 2;
b = 1 / (double)2;
c = (double)(1 / 2);
d = 1 / 2;
e = 1.0/2;
printf("a=%lf\nb=%lf\nc=%lf\nd=%lf\ne=%lf\n",a,b,c,d,e);
}
结果为:
?于是,可以通过如上第1、2、5两种方法,即:对被除数或除数添加强制类型转换,或将除数或被除数之一写为x.0的写法,来进行修正。
而原代码在将1改为1.0后正常运行,debug成功,程序正常运行。
?编程中整数和浮点数的运算规律与日常生活中的计算不尽相同,需要额外注意。
|