2016-10-17 2 views
0
#include "ieee754.h" 
#include <stdio.h> 
#include <math.h> 

//This program convert a floating number to its binary representation 
(IEEE754) in computer memory 
int main() 
{ 

long double f, binaryTotal, binaryFrac = 0.0, frac, fracFractor = 0.1; 
long int integer, binaryInt = 0; 
long int p = 0, rem, temp; 

printf("\nEnter floating number: "); 
scanf("%Lf",&f); 

//separate the integer part from the input floating number 
integer = (int)f; 

//separate the fractional part from the input floating number 
frac = f - integer; 

//loop to convert integer part to binary 
while(integer != 0) 
{ 
    rem = integer % 2; 
    binaryInt = binaryInt + rem *pow(10,p); 
    integer = integer/2; 
    p++; 
} 

//loop to convert fractional part to binary 
while(frac != 0) 
{ 
    frac = frac * 2; 
    temp = frac; 
    binaryFrac = binaryFrac + fracFractor * temp; 
    if (temp == 1) 
     frac = frac - temp; 

    fracFractor = fracFractor/10 ; 


} 

binaryTotal = binaryInt + binaryFrac; 
printf("binary equivalent = %Lf\n", binaryTotal); 


} 

Я пытаюсь преобразовать число с плавающим числом в двоичное представление (64-разрядное). Этот код работает, но не совершенен. Например, когда я конвертировать .575 это дает мне 0.100100, но когда я делаю преобразование, используя этот сайт http://www.exploringbinary.com/floating-point-converter/, правый выход должен быть 0,1001001100110011001100110011001100110011001100110011Преобразование плавающего числа в двоичную программу представления в C

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

+0

Compile со всеми предупреждениями поддержкой. –

+0

@MichaelWalz нет предупреждения: http: // ideone.com/aIShip – mch

+1

@mike вы должны написать, сколько цифр вы хотите после '.':' '% .20Lf' 'будет печатать' 0.10010011001100110011'. – mch

ответ

0

Вот почему это вряд ли будет работать:

fracFractor = 0.1 
... 
fracFractor = fracFractor/10 

0,1 не могут быть представлены точно в любом двоичном формате с плавающей точкой. Вы не можете представить 0,1 как кратное отрицательным степеням двух. Разделив его на 10, он будет собирать ошибки округления на каждом шагу. Возможно, вы получили этот цикл, чтобы фактически выйти, потому что вы в конечном итоге сравниваете повторяющуюся фракцию с другой повторяющейся фракцией.

И это будет серьезно ограничить то, что вы можете достичь:

binaryTotal = binaryInt + binaryFrac; 

Делать это в плавающей точкой будет иметь серьезные ограничения - не в меньшей мере, что представляющий 0,1 не представимо, как описано выше. Вот почему вы получаете ответы, представляющие собой сочетание двоичных и десятичных цифр.

Чтобы решить эту проблему, вам следует, вероятно, посмотреть отдельные биты числа. Чтобы общее представление о вашем решении было неповрежденным, самым легким будет удержание отрицательной мощности из двух (0,5, 0,25 и т. Д.) Из вашей фракции, проверка, если она по-прежнему положительная, и построить на ней строчку. Затем используйте аналогичную логику для целой части.

0

Многие проблемы:

  1. Используя (int), чтобы извлечь целую часть long double сильно ограничивает диапазон. Используйте modfl(long double value, long double *iptr);

    long double f; 
    long int integer; 
    //separate the integer part from the input floating number 
    // Weak code 
    integer = (int)f; 
    
    long double ipart; 
    long double fpart = modfl(f, &ipart); 
    
  2. long p; pow(10,p); -> потери точности в pow() возвращаемого значения раз p превышает некоторое значение (пример 25). Также странно использовать pow() с функцией, которая использует long double. Я ожидал бы powl().

  3. Различные другие неточные вопросы FP: fracFractor/10, ограниченная точность long.

Код странный, поскольку он пытается преобразовать номер FP (вероятно, в каком-то двоичном формате) в двоичное представление. Он не должен содержать 10 в любом месте кода.

Предложите что-то простое, как

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 
#include<float.h> 

static void print_ipart(long double x) { 
    int digit = (int) (modfl(x/2, &x)*2.0) + '0'; 
    if (x) { 
    print_ipart(x); 
    } 
    putchar(digit); 
} 

void print_bin(long double x) { 
    // Some TBD code 
    // Handle NAN with isnan() 
    // Handle infinity with isfinite() 

    putchar(signbit(x) ? '-' : '+'); 

    long double ipart; 
    long double fpart = modfl(fabsl(x), &ipart); 

    print_ipart(ipart); 
    putchar('.'); 
    while (fpart) { 
    long double ipart; 
    fpart = modfl(fpart * 2, &ipart); 
    putchar((int)ipart + '0'); 
    } 
    putchar('\n'); 
} 

int main() { 
    print_bin(-4.25); 
    print_bin(.575); 
    print_bin(DBL_MAX); 
    print_bin(DBL_MIN); 
    print_bin(DBL_TRUE_MIN); 
} 

Выход

-100.01 
+0.1001001100110011001100110011001100110011001100110011001100110011 
+1111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000. 
+0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 
+0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 
+0

Благодарим за помощь! Это очень сложный способ писать. Немного по сравнению с моим нынешним знакомством с C, хотя .. не могли бы вы объяснить, как (modfl (x/2, & x) * 2.0) + '0' работает? Я обнаружил, что modfl отдельно от fracpart, и я вижу использование деления 2. Я думаю, что мои вопросы - это то, что делает & x и почему вы умножаете его на 2? и вы ставите «0» в конце, когда x% 2 равно 0? Я думал, что этот проект конвертера станет хорошей практикой для написания кода C, но сейчас это немного выходит за рамки моего понимания. Я ценю вашу помощь. – mike

+0

@mike '& x' - это адрес' x'. 'modfl (lf, addr)' breaks 'lf' в часть дробной части, которая возвращается, и целую часть, которая сохраняется на указанном адресе. Результат функции - это дробь, в этом коде будет 0.0 или 0.5. Умножение на 2 делает это 0.0 или 1.0. Добавление этого значения в '' 0'' делает '' 0'' или '' 1'' для печати. Надеемся, что этот подход проще, чем ваш оригинал. Я не думаю, что это невозможно. – chux

+0

А теперь все ясно. Большое спасибо за вашу доброту. – mike

Смежные вопросы