#include <math.h>
#include <stdio.h>
void main() {
int decimal, count, binary, digit;
printf("Enter the number : ");
scanf("%d", &decimal);
count = 0; binary = 0;
while (decimal > 0) {
digit = decimal % 2;
binary = binary + digit * pow(10, count);
decimal = decimal / 2;
++count;
}
printf("Binary form : %d", binary);
}
我使用上面的代码将Decimal转换为二进制。但问题是输出。
Input : 12
Expected Output : 1100
Actual Output : 1099
[IMG] https://i.imgur.com/1mZlMQN.png[/img]
此问题也会持续存在于其他输入中。只有8给出了正确的输出。
有人可以解释为什么会这样吗?当我将它移植到那里时,这个错误也出现在C ++中。
PS:使用pow
检查一个号码是否是阿姆斯特朗以及它是否为回文时,也会弹出此错误。
答案 0 :(得分:5)
问题来自double
算术的精度有限。 pow(10, count)
可以计算为exp(log(10) * count)
,它可以产生一个非常接近但与实际整数结果不同的值。如果此值小于数学值,则转换为int
不会舍入到最接近,它将采用将是前一个整数的整数部分,因此99
而不是100
。< / p>
您应该使用整数算术:
#include <stdio.h>
int main(void) {
int decimal, binary, digit, pow10;
printf("Enter the number : ");
if (scanf("%d", &decimal) == 1) {
binary = 0;
pow10 = 1;
while (decimal > 0) {
digit = decimal % 2;
decimal /= 2;
binary = binary + digit * pow10;
pow10 *= 10;
}
printf("Binary form: %d\n", binary);
}
return 0;
}
请注意,您的代码中还存在其他一些问题:
main
原型是int main(void)
。scanf()
。2047
以下的整数值(使用32位int
)。以下是改进版本:
#include <limits.h>
#include <stdio.h>
int main(void) {
unsigned long long decimal;
printf("Enter the number: ");
if (scanf("%llu", &decimal) == 1) {
char binary[sizeof(decimal) * CHAR_BIT + 1];
char *p = binary + sizeof(binary);
*--p = '\0';
while (decimal > 1) {
*--p = '0' + (decimal & 1); // '0' or '1' for all encodings
decimal >>= 1;
}
*--p = '0' + decimal;
printf("Binary form: %s\n", binary);
}
return 0;
}
答案 1 :(得分:3)
pow(x, y)
最有可能被实现为exp(y * log(x))
,它可能会出现令人惊讶的小积分参数。如果结果被截断为整数,这将以特别的病态方式表现出来。
故事的寓意是在使用整数运算时避免使用pow
函数。
在您的情况下,保持连续乘以10
的运行系数是合适的。请注意,不要让int
类型溢出;上限可以小到32767
。
答案 2 :(得分:1)
我认为您的第一个问题是您的类型 - 您似乎想要构建二进制号码的整数表示,并且您还使用了pow,它的签名是:
double pow(double x, double y)
因此,您要将 double float 添加到整数。你确定要这么做吗?
您可能最好通过基本循环划分/ mod来构建字符串并打印它。这是在https://math.stackexchange.com/questions/111150/changing-a-number-between-arbitrary-bases
回答的此外,大或小的字节顺序可能会咬你,但这是在你的作业问题的范围内?