问题
I know that floating point cannot represent every number exactly so some error is bound to happen.
But recently I have encountered a problem and I am not getting the explanation right.
Please explain me step by step how the conversion affected the output.
How did truncating decimal places give me the wrong answer?
#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;
}
When I enter find octal equivalent of 1701
. It gives answer 3244
.
What I want to know is how does the program working?
How is the program printing 3244
and not 3245
.
But the answer is 3245
.
I have checked that x%8
is correctly working .
When I change the y
data type to float, it works .
Why so?
Please explain me step by step how the conversion affected the output.
How did truncating decimal places give me the wrong answer?
回答1:
When you convert from a floating-point type to an integer type, the machine will truncate the decimal places, not round.
回答2:
Enter The Number You Want To Octal Equivalent Of : 1701
5
45
245
3245
try this see if it helps (dont need to link in a math library)
#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;
}
and I assume you know you can do this?
#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;
}
or take an ascii approach
#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;
}
or many other solutions...
#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;
}
EDIT
1701 = 0x6A5 = 0b011010100101
so if you group the binary number in fours you can see the hex value (start from the right)
0110 1010 0101 = 0x6A5
if you break it into groups of three you see the octal
011 010 100 101 = 03245
and you can see how the last solution I showed works, tack a zero on each of these
011 010 100 101
0011 0010 0100 0101
and you get 0x3245
, exactly what you were doing with base 10 but with base 16 instead and taking advantage of the optimization of using shifts and masks.
EDIT 2
understand how much is going on in this one line of code (assume x and y are int)
y = y + (x%8)*pow(10,n);
first off order of operations. the compiler is welcome to and should do the modulo first resulting in an int
. Next order of operations, parenthesis would remove all doubt. the multiply is next but one operand is a double (pow)
so the result of the modulo has to be promoted to double
. and the double multiply happens. now you have the add one side is int
the other double
. so this y is promoted to double
, the double
add happens then the double
to int
happens to store in y
. If you look at my first simpler example making n go 1, 10, 100, 1000
, etc as an int
then there is no double
promotion it stays int
all the time.
if you make y
a float
, then the add is a float + double
so y
has to be promoted to a double, the double add happens as before, but now the storage to the left side of the equals, as a float
, you have a double
to float
conversion, which allows for rounding. so each time through the loop you allow the opportunity for a little fraction to land in y
. problem here, at least with your examples, I dont see any fractions that the floating point format cannot handle. the modulo is supposed to be done as an int
and there is no fraction. if you change x
to a float
, then sure you will have problems.
来源:https://stackoverflow.com/questions/33328560/float-to-integer-casting