我正在尝试编写一个方法来确定给定的数字是否是一个非常强的数字。通过以下步骤可以找到一个阿姆斯特朗号码:
如果总和等于原始数字,那么就是武器,即405!= 456,所以不是武器。
int armstrong(float number){
if(number < 1){
return 0;
}
else{
float *pointer = malloc(sizeof (float)), *temp;
if(pointer == NULL){
printf("Error allocating memory: math::armstrong.\nReturn value 0.");
return 0;
}
else{
int temp_boolean = 1, index = 0;
float sum = 0, original_number = number;
while(temp_boolean == 1){
if(number / 10 == 0){
temp_boolean = 0;
}
else{
temp = realloc(pointer, ((sizeof pointer / sizeof (float)) + 1) * sizeof (float));
pointer = temp;
}
pointer[index] = fmod(number, 10.0);
//pointer[index] = number % 10;
number /= 10;
++index;
}
int i;
for(i = 0; i < index; ++i){
float temp_e = pointer[i];
sum += pow(temp_e, index);
}
free(pointer);
if(sum == original_number){
return 1;
}
else{
return 0;
}
}
}
}
如果给定的数字是阿姆斯特朗号,我的程序返回1,否则返回0。现在,当我将变量和参数作为int时,这可以正常工作,但我希望能够接收更大的数字,这就是为什么我的代码在float中有变量的原因。但由于某种原因,它没有提供任何输出。它使用-Wall选项编译好gcc,所以我不知道我做错了什么。
我使用notepad ++编写我的程序,使用gcc编译。
答案 0 :(得分:4)
类型float
的变量支持更大范围的值,但通过不表示范围中的每个可能值来实现此目的。例如,假设float
的大小为32位且int
为32位,则int
可以表示一些整数值,但float
不能。< / p>
您的代码依赖于您做出的假设,float
可以表示每个整数值。如果该假设不正确 - 至少会有一些较大的积分值 - 那么你的功能就会失灵。
如果您希望函数适用于较大的值,请尝试找到一种表示较大积分值的方法(超出内置类型可以表示的范围)。执行此操作有很多选项,但一种方法是传递char
数组,其中数组中的每个元素都代表一个整数位(例如0
- 9
)。与此相关的是,您需要模拟您所选择的所有操作(除法,模数,求和,乘以10的幂等)。
答案 1 :(得分:3)
使用float
因为“想要存储更大的数字”是一个坏主意。 float
只有大约6位数的精度,所以一旦你开始存储数百万,你就已经失去了精度。 double
类型,无论如何都是“默认”浮点大小,具有~15位精度,但如果你想处理“真正的大整数”,它仍然不是解决方案。
那里有很多bignum图书馆,gmplib就在其中。
其他图书馆有时会为自己的目的提供bignum支持,您也可以使用,例如BN_ functions of OpenSSL。只是在寻找,并抵制重新发明轮子的诱惑 - bignum实现很容易找到,并且非常成熟。
除此之外,我在您的代码中看到sum == original_number
- 因为浮点数不是精确,检查相等并不是一个好主意无论是。 (海湾合作委员会的-Wfloat-equal
可以提醒您这一点,我建议您将其添加到已启用的警告列表中。)