浮动整数铸造?

我知道浮点数不能完全代表每个数字,因此必然会发生一些错误。

但最近我遇到了一个问题,我没有得到正确的解释。

请逐步解释转换如何影响输出。

截断小数位如何给我错误的答案?

#include #include #include 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时,它可以正常工作。 为什么这样?

请逐步解释转换如何影响输出。
截断小数位如何给我错误的答案?

当您从浮点类型转换为整数类型时,机器将截断小数位,而不是舍入。

 Enter The Number You Want To Octal Equivalent Of : 1701 5 45 245 3245 

试试看看它是否有帮助(不需要在数学库中链接)

 #include #include 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 #include 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 #include 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 #include 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)<>=3; } printf("Octal Equivalent is : %X\n",y); return 0; } 

编辑

1701 = 0x6A5 = 0b011010100101

因此,如果您将二进制数分组为四,则可以看到hex值(从右侧开始)

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 。 所以这个y被提升为doubledouble添加发生,然后doubleint恰好存储在y 。 如果你看一下我的第一个更简单的例子,将n转1, 10, 100, 1000等作为int那么就没有double促销它一直保持int

如果你使y成为一个float ,那么add是一个float + double所以y必须被提升为double,双重添加就像以前一样,但是现在存储到equals的左边,作为一个float ,你有double to float转换,允许舍入。 所以每次通过循环你都有机会让一小部分降落在y 。 问题在这里,至少在你的例子中,我没有看到浮点格式无法处理的任何分数。 模数应该作为int来完成,并且没有分数。 如果你将x改为float ,那么你肯定会遇到问题。