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
, то наверняка у тебя будут проблемы.