首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pow函数出错

pow函数出错
EN

Stack Overflow用户
提问于 2017-09-17 02:21:17
回答 3查看 1.1K关注 0票数 0
代码语言:javascript
复制
#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转换为binary。然而,问题在于输出。

代码语言:javascript
复制
Input           : 12
Expected Output : 1100
Actual Output   : 1099

imghttps://i.imgur.com/1mZlMQN.png[/img]](https://i.imgur.com/1mZlMQN.png[/img])

对于其他输入,这个问题也存在。只有8给出了正确的输出。

那么,谁能解释一下为什么会发生这种情况?当我将它移植到C++中时,这个错误也会出现。

PS:在使用pow检查数字是否为阿姆斯特朗以及是否为回文时,也会出现此错误。

EN

回答 3

Stack Overflow用户

发布于 2017-09-17 02:39:56

这个问题来自于double算法的有限精度。可以将pow(10, count)计算为exp(log(10) * count),这可以生成一个非常接近但不同于实际整数结果的值。如果此值小于数学值,则转换为int不会舍入到最接近的值,它将采用前一个整数的整数部分,因此是99而不是100

相反,您应该使用整数运算:

代码语言:javascript
复制
#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;
}

请注意,您的代码中还存在一些其他问题:

int main(void).

  • You不带参数的

  • main的原型应该在输出的末尾打印换行符。

  • 您应该测试scanf().

  • Your方法的返回值本质上限制为小于2047的整数值(使用32位int).

以下是一个改进的版本:

代码语言:javascript
复制
#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;
}
票数 5
EN

Stack Overflow用户

发布于 2017-09-17 02:37:43

pow(x, y)最有可能被实现为exp(y * log(x)),这可能会在整型参数小得惊人的情况下失效。如果结果被截断为整数,这将以一种特别病态的方式表现出来。

这个故事的寓意是在处理整数运算时避免使用pow函数。

在您的例子中,保持一个连续乘以10的运行系数是合适的。只需小心不要溢出您的int类型;上限可能与32767一样小。

票数 3
EN

Stack Overflow用户

发布于 2017-09-17 02:43:16

我认为你的第一个问题是你的类型-你似乎想要构建一个二进制数的整数表示,而且你还在使用pow,它的签名是:

代码语言:javascript
复制
double pow(double x, double y)

所以你要把一个双精度浮点数加到一个整数上。你确定要这么做吗?

您最好执行divide by/mod by base循环,然后构建一个字符串并打印出来。答案在这里,https://math.stackexchange.com/questions/111150/changing-a-number-between-arbitrary-bases

此外,大的或小的字节顺序可能会影响你,但这在你的家庭作业问题的范围内吗?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46257089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档