我尝试制作一个C程序,将用户输入的十进制数转换为八进制数。我用自己的逻辑编写了C代码,没有研究其他用户如何尝试这样做。它适用于数字601
和其他一些数字,但对于大多数数字,它返回八进制等效值,最后一个数字比它应该小1
。对于75
,它会返回112
而不是113
。我意识到使用printf
和%o
完成工作但是它有点挫败了学习编程的目的。这是我的代码:
#include <stdio.h>
#include <math.h>
/* converting decimal to octal */
int main()
{
int n,x,y,p,s;
printf("Enter a decimal number ");
scanf("%d",&x);
s=0;p=0;
while (x!=0)
{
y=x%8;
s=s+y*pow(10,p);
x=(x-y)/8;
p=p+1;
}
printf("the octal equivalent is: %d\n",s);
getch();
return 0;
}
答案 0 :(得分:6)
这是一种有趣的方式。我将仅就原创性问题进行投票。
通过添加软糖因子来解决问题:
s = s + y*pow(10,p) + 0.1;
问题是浮点精度。其中一个粉末计算返回类似于99.99999999999992而不是100.转换回int失去0.999 ...分数并得到99而不是100.或999而不是1000.它不在一个位置,因为零指数是一个完全得到1.0的特殊情况。
顺便说一句,因为你只能在32位int中得到9位数,所以susmit的建议是以int形式乘以10的幂是非常合理的。除特殊情况外,pow将计算pow(x,y)为exp(y * log(x))。 exp()和log()往往是昂贵的计算。
顺便说一下,即使通过强制exp和日志计算,我也无法重现这个问题。我得到(10 + 1.8e-15),(100 + 4.3e-14)和(1000 + 6.8e-13)的值,所有舍入都正确,因为错误全部为正。这是在x86上,我相信我用VC ++ 2008编译了这个计算器。你使用什么编译器?
答案 1 :(得分:1)
替代第一个答案,而不是
s=s+y*pow(10,p);
有一个shiftfactor,初始化为1,然后执行
s += y*shiftfactor;
shiftfactor *= 10;
此外,而不是x =(x-y)/ 8;只需x / = 8即可;由于整数舍入。
答案 2 :(得分:0)
#include <stdio.h>
#include <math.h>
/* converting decimal to octal */
int main()
{
int n, x, y, p;
double s = 0;
printf("Enter a decimal number ");
scanf("%d", &x);
p = 0;
while (x != 0)
{
y = x % 8;
s = s + (double)y * pow(10, p);
x = ( x - y ) / 8;
p = p + 1;
}
printf(“八进制等效值为:%lf \ n”,s);
返回0; }
我认为这可以解决您的问题。实际上Pow()返回double值。在您的代码中,您使用了int,因此小数部分将被截断,并将变量放入变量's'。
答案 3 :(得分:0)
#include <stdio.h>
int main()
{
int d_num = 0;
int o_num = 0;
int factor = 1;
printf("Enter a decimal number: ");
scanf("%d", &d_num);
while (d_num > 0) {
o_num += d_num % 8 * factor;
d_num /= 8;
factor *= 10;
}
printf("Octal equivalent: %d\n", o_num);
return 0;
}
对我来说,这段代码只能进行整数运算。
答案 4 :(得分:0)
为什么你需要使用x=(x-y)/8
。为什么你不能使用x=x/8
。它与lhs和rhs中使用的变量类型的效果相同,都是整数。顺便说一下代码对我有用。我认为问题在于整数舍入。只需将x=(x-y)/8
替换为x=x/8
答案 5 :(得分:0)
OP前一段时间解决了这个问题,但我想我会提出一个简单的解决方案。
/* converting decimal to octal */
unsigned decimal_to_octal(unsigned x) {
if (x < 8) {
return x;
}
return decimal_to_octal(x/8)*10 + x%8;
}
测试代码
unsigned test10to8(void) {
for (;;) {
unsigned x;
scanf("%d", &x);
printf("x:%u y:%u\n", x, decimal_to_octal(x));
}
}