Float To Integer Casting?

做~自己de王妃 提交于 2019-12-08 11:37:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!