本文章解决的问题是:整形计算赋值给浮点数变量时,浮点变量数值看似异常的问题。问题很基础,适合给同样刚刚开始学习C语言的编程小白参考,且主要作用是希望大家引以为戒,不要犯和作者一样的错误。
在做题目的过程中发现关于double类型的一个问题:
原题目是:由用户输入项数,计算如下两个无穷级数:
原代码如下:
//练习题6.16.12.c -- 无穷级数 #includeint 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项和为:%lfnn",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 #includevoid 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=%lfnb=%lfnc=%lfnd=%lfne=%lfn",a,b,c,d,e); }
结果为:
于是,可以通过如上第1、2、5两种方法,即:对被除数或除数添加强制类型转换,或将除数或被除数之一写为x.0的写法,来进行修正。
而原代码在将1改为1.0后正常运行,debug成功,程序正常运行。
编程中整数和浮点数的运算规律与日常生活中的计算不尽相同,需要额外注意。



