这个 C++ 十进制到二进制转换代码有啥问题?
Posted
技术标签:
【中文标题】这个 C++ 十进制到二进制转换代码有啥问题?【英文标题】:What is wrong with this C++ decimal to binary conversion code?这个 C++ 十进制到二进制转换代码有什么问题? 【发布时间】:2021-11-08 05:56:21 【问题描述】:对于某些值(如 9),它可以完美运行,但对于大多数(如 7、19 或 6),它会从返回(二进制)值中减去 1。
#include<iostream>
#include<cmath>
using namespace std;
int decimaltobinary(int);
int main()
int num;
cout<<"Enter the number: ";
cin>>num;
cout<<num<<" in decimal = "<<decimaltobinary(num)<<" in binary.";
return 0;
int decimaltobinary(int num)
int remainder,i=0,binary=0;
while(num!=0)
remainder=num%2;
num=num/2;
binary=binary+remainder*pow(10,i);
i++;
return binary;
【问题讨论】:
问题是你对你用哪种语言编程感到困惑。代码是C++,但你已经标记了C语言。仅供参考,C 语言没有std::cout
也没有std::cin
。我建议您更新语言标签。
pow
使用不精确的浮点数。它可能会引入您看到的一个错误。如果您从1
开始i
,则可以将其乘以10
而不是递增。然后你可以使用i
而不是pow(10,i)
,后者只会使用整数。
十进制和二进制是值的文本表示。将值转换为其二进制表示意味着将其转换为文本。
而不是pow(10, i)
,只是在循环之前累积乘数:int i = 1;
,在循环中执行binary = binary + i * remainder; i *= 10;
。
该程序对我来说运行良好(如果 num
【参考方案1】:
显示的代码有两个主要问题:
-
所示代码尝试构建输入数字的二进制版本十进制,例如,
111
的结果为数字 7。这是一个111 的整数值。
在 32 位平台上,使用 32 位整数意味着可以通过这种方式“转换”为十进制的最大数字是 2047。2048 是二进制的 10000000000,这将超过 32 位整数的容量。一个无符号的 32 位整数的最大值是 4294967295(其中一半是普通的有符号 int
值,但无论是有符号还是无符号,此时您都没有精力了)。
-
默认情况下,
pow()
与两个整数值的任何使用都会自动中断,因为floating point math is broken。这不是pow()
真正做的。 pow()
的作用如下:a) 它取其第一个参数的自然对数,b) 将步骤 a 的结果乘以其第二个参数,c) 将 e
提高到步骤 b 的幂。这听起来像您期望在这里做的事情吗?
由于pow()
采用浮点参数,结果是浮点数,所以显示代码的最终结果是一堆浮点数和整数值之间不必要的转换,并导致非特定的舍入错误不精确的浮点指数数学。
但所示代码中的主要缺陷是尝试使用普通的int
s 来组装表示二进制值的十进制数,而二进制值根本没有足够的位数。切换到long long int
不会有太大帮助。用我的手指数数,那样的话,你只能上升到一百万以北的某个地方。对于所描述的编程任务,必须采用完全不同的方法。
【讨论】:
【参考方案2】:您的问题是 binary+remainder*pow(10,i);
全部在浮点运算中完成,并且仅在分配时转换为 int
。由于pow
不精确,您可能会得到略低于精确值的结果,在这种情况下,转换会截断它并使其比所需结果小 1。
虽然有多种更好的方法可以实现您的目标,但直接的解决方法是使用 std::round()
,然后将结果转换为 int:
binary=binary+remainder*int(round(pow(10,i)));
【讨论】:
以上是关于这个 C++ 十进制到二进制转换代码有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章