Float To Integer Casting?

Я знаю, что число с плавающей запятой не может точно представлять каждое число, поэтому обязательно произойдет какая-то ошибка.

Но недавно я столкнулся с проблемой, и я не понимаю объяснения правильно.

Пожалуйста, объясните мне шаг за шагом, как преобразование повлияло на результат.

Как усечение десятичных знаков дало мне неправильный ответ?

#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 Тип данных, чтобы плавать, это работает. Почему так?

Пожалуйста, объясните мне шаг за шагом, как преобразование повлияло на результат.
Как усечение десятичных знаков дало мне неправильный ответ?

2 ответа

Когда вы конвертируете из типа с плавающей точкой в ​​целочисленный тип, машина будет усекать десятичные знаки, а не округлять.

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, так что это у повышен до double, double добавить происходит тогда double в int случается хранить в y, Если вы посмотрите на мой первый более простой пример 1, 10, 100, 1000и т. д. как int тогда нет double продвижение остается int все время.

если вы сделаете y floatто добавление является float + double так y должно быть повышено до двойного, двойное добавление происходит, как и раньше, но теперь хранилище слева от равенства, как float, у тебя есть double в float преобразование, которое позволяет для округления. так что каждый раз через цикл вы даете возможность небольшому количеству приземлиться в y, Проблема здесь, по крайней мере с вашими примерами, я не вижу дробей, которые формат с плавающей запятой не может обработать. модуль должен быть сделан как int и нет дроби. если вы измените x к float, то наверняка у тебя будут проблемы.

Другие вопросы по тегам