2015-10-25 4 views
0

Я знаю, что плавающая точка не может представлять каждое число точно так, чтобы произошла какая-то ошибка.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 для плавания, он работает. Почему так?

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

+0

Усечение и ошибка с плавающей точкой. –

+0

Что я хочу знать, шаг за шагом, как усечение десятичных знаков дает мне 1 меньше, чем предполагаемый ответ. Я не знаю, почему люди голосуют за мой вопрос. –

+0

Ваш 'pow (10, n)' не предоставляет ожидаемые ответы _exact_. Добавьте 'printf ("%.20e% d \ n ", pow (10, n), (int) pow (10, n)),' в цикл, чтобы увидеть неожиданное. – chux

ответ

3

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

+0

Можете ли вы разработать? где именно ошибка сделана? когда я добавляю 'printf ("% d ", y);' он показывает '5 45 244 3244' .. как выполняется кастинг? и вы сказали, что машина будет обрезать десятичные знаки не круглыми? но я преобразовал только целое число без десятичной точки в float. Я имею в виду, если 'x = 4'. затем float 'x = 4.00000'. Так что даже если вы усекаете десятичные знаки. Номер не должен меняться. Я здесь что-то не так? –

+0

Сэр, я должен сделать запрос. Этот вопрос, который я задал, потому что мне нужно знать, и это вызвало недовольство. Этот вопрос заслуживает голосования, это было настоящее сомнение. Из-за этого я не могу задавать вопросы, поскольку они не соблюдаются. Я хочу знать, что вы думаете, что этот вопрос неправильный и заслуживает понижения? –

0
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; 
} 

EDIT

1701 = 0x6A5 = 0b011010100101

так что если вы группа двоичное число в четвереньках вы можете увидеть шестнадцатеричное значение (начиная с права)

0110 1010 0101 = 0x6A5

если вы разбиваете его на группы по три, вы видите восьмеричный

011 010 100 101 = 03245

и вы можете увидеть, как последнее решение, которое я показал работы, лавировать нуль на каждом из этих

011 010 100 101

0011 0010 0100 0101

и вы получите 0x3245, именно то, что вы делали с базой 10, но с базой 16 вместо этого, и использовали оптимизацию использования смен и масок.

EDIT 2

понять, сколько происходит в этой одной строке кода (предположим, что х и у ИНТ)

y = y + (x%8)*pow(10,n);

первого порядка от операций. компилятор приветствуется и должен делать по модулю первый результат в int. Следующий порядок операций, скобки, устранит все сомнения. умножение следующего, но один операнд - double (pow), поэтому результат модуляции должен быть повышен до double. и происходит двойное умножение. теперь у вас есть добавка одна сторона int другая double. поэтому этому y присваивается значение double, тогда происходит добавление double, а double - int - хранится в y. Если вы посмотрите на мой первый более простой пример, сделав n go 1, 10, 100, 1000 и т. Д. Как int, тогда нет double, он остается int все время.

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

+0

Я взял y как float, и он решил проблему, и я тоже пробовал ваши решения. Что означает 'x = x >> 3'? –

+0

преобразование числа в восьмеричное с двоичной перспективы означает принимать по три бита за раз. возьмите три с правой стороны вправо три раза три, повторите до конца. меньше вычислительной мощности, но оба решения работают. pow() перетаскивает двойные поплавки в микс, что приводит к переполнению даже для решения математической основы проблемы. что линия сдвигается вправо 3 (деление на 2 на мощность 3 = 8) сдвигает нули в верхнем –

+1

'x = x >> 3' является запутанным способом записи' x = x/8' для положительных чисел и имеет недостаточно четкое поведение для отрицательных чисел. –