/*
Description
输出所有的水仙花数。所谓水仙花数是一个3位的正整数,其各位数字的立方和等于这个数本身。
例如,153是水仙花数,因为1^3+5^3+3^3=153。 ^代表上标
输入格式
无
输出格式
一行一个,由小到大输出所有水仙花数
*/
# include <stdio.h>
# include <math.h>
int main()
{
int i, j, k, l;
int sum = 0;
for (i = 100; i <= 999; i++,sum = 0)
{
for (j = i; j != 0; j /= 10)
{
k = j % 10;
/*研究该关键行代码*/
sum = sum + pow(k, 3);//如果把pow(k, 3)转换为float或double或者把 整个表达式强制转换成int类型 则不会出现问题
/*也可改成:
k = j % 10;
l = k * k * k;
sum += k*k*k;
*/
/*查看代码执行过程,发现一到含有5的数字就出问题,可以查看执行结果为水仙花数i = 153或 i = 155的那行代码的输出结果
已知:pow()函数是用float单精度浮点型进行计算的,返回值为float类型;如果用%d 输出,则会出现精度丢失,返回值为0
问题:但是为什么会出现pow(5^3)==124这种情况呢,可查看执行结果为水仙花数i = 153或 i = 155的那行代码的输出结果
*/
printf(" i = %d,j = %d, k = %d, sum = %d\n",i, j, k, sum);//
if (sum > i)
{
break;
}
}
if (i == sum)
{
printf("%d\n", i);
}
}
return 0;
}
在codeblocks中,上述代码输出结果:
查看代码执行过程,发现一到含有5的数字就出问题,可以查看执行结果为水仙花数i = 153或 i = 155的那行代码的输出结果
/* 已解决的疑问1和疑问2:
如果把一个浮点数赋值给整型变量,则会截断小数部分,只保留整数部分
pow()函数是把数据转换成float单精度浮点型进行计算的,如果用%d 输出,则会出现精度丢失,输出0;
//上述疑问1和疑问2的测试程序:
# include <stdio.h>
# include <math.h>
int main()
{
int i = 5;
double j = pow(5, 3);
double k = 2.22;
int l = k;
printf("用%%d输出整型数据:i = %d\n\n",i);
printf("用%%d输出pow(5,3)函数:j = %d\n\n", j);
printf("用%%f输出pow(5,3)函数:j = %f\n\n", j);
printf("截断浮点型数据 %lf 的小数部分并输出:l = %d\n", k, l);
return 0;
}
上述代码,在codeblocks中的输出结果:
已解决疑问:
- pow()函数在水仙花数中为何会出现 : k = 5; pow(k, 3) = 124
//疑问3的测试程序:
# include <stdio.h>
# include <math.h>
int main()
{
int k;
int j = 0;
int sum = 0;
k = 5;
sum = pow(k, 3);
j = pow(5, 3);
printf("k = %d, sum = %d, j = %d\n", k, sum, j);
return 0;
}
在codeblocks中的输出结果:
在Dev-C++中输出的结果:
在Visual Studio 2019中输出的结果:
原因:
由于编译器和编译环境的差异,仅在codeblocks编译器中会出现 k = 5; pow(k,3) = 124 的问题,而在Dev-C++和VS2019中不会出现该问题,并且该水仙花程序在OJ中能正确得出 pow(k, 3) = 125 并且 AC