版权声明:个人学习笔记记录 https://blog.csdn.net/Ratina/article/details/84245745
最近被人问到一道题:
输入两个整数n<m<106,输出1/n2+1/(n+1)2+…+1/m2,保留5位小数。
一开始是这样写的
int i;
double sum=0;
for(i=n;i<=m;i++)
sum+=1/(double)(i*i);
printf("%.5f",sum);
结果错了。
为什么呢,因为n,m最大是106,平方之后是1012,而32位int类型最多存放10位十进制数,导致了数据丢失。
两种改进方法:
long long i;
double sum=0;
for(i=n;i<=m;i++)
sum+=1/(double)(i*i);
printf("%.5f",sum);
①将 i 声明为long long类型 ( long和32位int是一样的,long同样不够 ),这样 i * i 的值就存得下了。
int i;
double sum=0;
for(i=n;i<=m;i++)
sum+=1/((double)i*(double)i);
printf("%.5f",sum);
②将两个 i 分别强制类型转换成double类型,再相乘。
再者,关于数据类型的转化补充一些。
①自动类型转换,发生在以下4种情况:
1、算术运算式中,低类型能够转换为高类型。
2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。
3、函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。
4、函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。
Ps.字符型会转换为整型。
②强制类型转换:
(类型说明符) (表达式)
数据类型转换时,一般低类型转换为高类型,不会丢失数据,而高类型向低类型转换,会发生数据丢失。(主要与数据的存储位数有关)(而浮点型转换为整型会去除小数)
因此,这里int、long long转double就不会丢失数据。
参考资料:https://blog.csdn.net/cherish_2012/article/details/21243047