复合赋值运算符返回错误值(十进制到二进制转换)

问题描述 投票:0回答:1

我正在尝试编写一个 C 程序将十进制转换为二进制。以下代码可以将十进制整数转换为二进制。

#include <stdio.h>
#include <math.h>

int main()
{
    long int n;
    printf("Enter a Positive Integer (decimal): ");
    scanf("%d", &n);
    long int temp = n;
    int r;  long long int bin = 0;
    int p = 0;

    while(temp > 0)
    {
        r = temp % 2;   printf("%d\t", r); // printing r value for debugging
        bin += (r * pow(10, p));
        temp /= 2;
        p++;
    }
    printf("\n%lld", bin);
    
    return 0;
}

我已经测试了多个随机值的代码,并获得了大多数随机值的预期输出,除了两个特定值“99999”和“419862”。对于“99999”,预期输出是“11000011010011111”,但我得到“11000011010011112”。对于“419862”,预期输出是“1100110100000010110”,但我得到“1100110100000010112”。除最后一个数字外的所有数字均正确匹配。获得“2”而不是“1”和“0”。为了调试代码,我在

printf("%d\t", r);
语句之后立即添加了
r = temp % 2;
。如此打印的r值给出了正确的预期输出。这是输出:

对于“99999”,输出为

Enter a Positive Integer (decimal): 99999
1   1   1   1   1   0   0   1   0   1   1   0   0   0   0   1   1   
11000011010011112

对于“419862”,输出是

Enter a Positive Integer (decimal): 419862
0   1   1   0   1   0   0   0   0   0   0   1   0   1   1   0   0   1   1   
1100110100000010112

注意:单独打印的r值是相反的。

为什么第一个余数分别使用

printf("%d\t", r);
'1' 和 '0' 打印 (对于'99999'和'419862'),但是复合赋值得到的bin值的个位数不一样?

c binary decimal compound-assignment
1个回答
0
投票

bin += (r * pow(10, p));
的意思是
bin = bin + (r * pow(10, p));
。 (N1570 6.5.16.2 复合赋值)

根据通常的算术转换(N1570 6.3.1.8),乘法

*
和加法
+
当其中一个操作数是
double
(而另一个是实数类型而不是
时)将产生
double
结果long double
)。

pow
函数 (N1570 7.12.7.4) 返回
double
,因此
r * pow(10, p)
具有类型
double
,因此
bin + (r * pow(10, p))
也具有
double
类型。

通常使用 64 位 IEEE754 格式来表示

double
。据说这种格式的精度大约是15位小数。

在输入

99999
的最后一次迭代中,添加值
1000011010011111
10000000000000000
。它们分别有 16 和 17 位数字。 这超出了 15 位数字的限制,出现精度错误的机会会很高。

总之,您会遇到舍入错误,因为您使用了浮点值,而应使用具有多位数字的整数。

例如,在这种情况下可以通过这种方式消除使用

pow
(使用乘数变量
mult
并增量乘以
10
,而不是在每次迭代中计算功率):

    long long int mult = 1;
    while(temp > 0)
    {
        r = temp % 2;   printf("%d\t", r); // printing r value for debugging
        bin += (r * mult);
        temp /= 2;
        mult *= 10;
    }
© www.soinside.com 2019 - 2024. All rights reserved.