我知道浮点数不能完全代表每个数字,因此必然会发生一些错误。
但是最近我遇到了一个问题,我没有得到正确的解释。
请逐步解释转换如何影响输出。
截断小数位是如何给出错误答案的?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
int x;
int y = 0;
int n = 0;
printf("Enter The Number You Want To Octal Equivalent Of : ");
scanf("%d",&x);
while(x>0)
{
y = y + (x%8)*pow(10,n);
printf("%d\n" , y);
x = x/8 ;
n = n + 1;
}
printf("Octal Equivalent is : %d" , y);
return 0;
}
当我输入找到1701
的八进制等值时。它给出了答案3244
。
我想知道的是程序是如何工作的?
该程序如何打印3244
而不是3245
。
但答案是3245
。
我已检查x%8
是否正常工作。
当我将y
数据类型更改为float时,它可以正常工作。
为什么这样?
请逐步解释转换如何影响输出 截断小数位是如何给出错误答案的?
答案 0 :(得分:3)
当您从浮点类型转换为整数类型时,机器将截断小数位,而不是舍入。
答案 1 :(得分:0)
Enter The Number You Want To Octal Equivalent Of : 1701
5
45
245
3245
尝试看看它是否有帮助(不需要在数学库中链接)
#include<stdio.h>
#include<stdlib.h>
int main()
{
int x;
int y = 0;
int n = 1;
printf("Enter The Number You Want To Octal Equivalent Of : ");
scanf("%d",&x);
while(x>0)
{
y = y + ((x%8)*n);
printf("%d\n" , y);
x = x/8 ;
n = n * 10;
}
printf("Octal Equivalent is : %d" , y);
return 0;
}
我猜你知道你能做到吗?
#include<stdio.h>
#include<stdlib.h>
int main()
{
int x;
int y = 0;
int n = 1;
printf("Enter The Number You Want To Octal Equivalent Of : ");
scanf("%d",&x);
while(x>0)
{
y = y + ((x&7)*n);
printf("%d\n" , y);
x = x>>3 ;
n = n * 10;
}
printf("Octal Equivalent is : %d" , y);
return 0;
}
或采取ascii方法
#include<stdio.h>
#include<stdlib.h>
int main()
{
int x;
int y = 0;
int n = 0;
char output[16];
printf("Enter The Number You Want To Octal Equivalent Of : ");
scanf("%d",&x);
while(x)
{
output[n++]=(x&7)+0x30;
x = x>>3 ;
}
output[n]=0x30;
printf("Octal Equivalent is : ");
while(n>=0)
{
printf("%c",output[n--]);
}
printf("\n");
return 0;
}
或许多其他解决方案......
#include<stdio.h>
#include<stdlib.h>
int main()
{
int x;
int y = 0;
int n = 0;
printf("Enter The Number You Want To Octal Equivalent Of : ");
scanf("%d",&x);
while(x)
{
y |= (x&7)<<n;
n+=4;
x>>=3;
}
printf("Octal Equivalent is : %X\n",y);
return 0;
}
修改强>
1701 = 0x6A5 = 0b011010100101
因此,如果您将二进制数分组为四,则可以看到十六进制值(从右侧开始)
0110 1010 0101 = 0x6A5
如果你把它分成三组,你会看到八进制
011 010 100 101 = 03245
你可以看到我展示的最后一个解决方案是如何工作的,对每个解决方案都是零
011 010 100 101
0011 0010 0100 0101
然后你得到0x3245
,正是你用10号基础做的,但是用16号基础进行,并利用了使用移位和掩码的优化。
编辑2
了解这一行代码中的进展情况(假设x和y为int)
y = y + (x%8)*pow(10,n);
首先关闭操作顺序。我们欢迎编译器,并且应该首先使用模数生成int
。下一步操作,括号将消除所有疑问。乘法是下一个,但是一个操作数是double (pow)
,因此模数的结果必须提升为double
。并且双倍乘法发生。现在你添加一方是int
另一方double
。因此,此y被提升为double
,double
添加发生,然后double
到int
恰好存储在y
中。如果您查看我的第一个更简单的示例,即将1, 10, 100, 1000
等作为int
,那么就不会double
促销int
一直保持y
。
如果您float
float + double
,则添加为y
,因此必须将float
提升为双倍,双重添加与以前一样,但现在存储在等于左侧的存储,作为double
,您进行float
到y
转换,允许进行舍入。所以每次通过循环你都有机会让一小部分落在int
。问题在这里,至少在你的例子中,我没有看到浮点格式无法处理的任何分数。模数应该以{{1}}完成,并且没有分数。如果您将x
更改为float
,那么请确定您会遇到问题。