浮动整数铸造?
我知道浮点数不能完全代表每个数字,因此必然会发生一些错误。
但最近我遇到了一个问题,我没有得到正确的解释。
请逐步解释转换如何影响输出。
截断小数位如何给我错误的答案?
#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被提升为double
, double
添加发生,然后double
到int
恰好存储在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
,那么你肯定会遇到问题。