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 비트)으로 변환하려고합니다. 이 코드는 작동하지만 완벽하지는 않습니다. 예를 들어 나는 0.575를 변환 할 때, 그것은 나에게 0.100100을 제공하지만이 웹 사이트 http://www.exploringbinary.com/floating-point-converter/를 사용하여 변환을 할 때 문제가 내 코드 수를 절단하는 무슨 이해하는 데 0.1001001100110011001100110011001100110011001100110011C에서 부동 소수점을 이진 표현 프로그램으로 변환

오른쪽 출력해야한다. 아무도 그것을 고칠 수있는 방법을 도와 줄래? 도와 주셔서 감사합니다. 이 작업을하지 않을 이유

+0

컴파일 같은 간단한 것을 제언한다. –

+0

@MichaelWalz 경고가 없습니다. http : // ideone.com/aIShip – mch

+1

@mike'.' :' "% .20Lf"'가'0.10010011001100110011'을 인쇄 한 후에 원하는 자리수를 써야합니다. – mch

답변

0

은 다음과 같습니다

fracFractor = 0.1 
... 
fracFractor = fracFractor/10 

0.1은 이진 부동 소수점 형식으로 정확하게 표시 할 수 없습니다. 0.1을 2의 음수 배수로 나타낼 수 없습니다. 10으로 나누면 모든 단계에서 반올림 오류가 수집됩니다. 반복되는 분수와 다른 반복 분수를 비교하기 때문에 실제로 종료 할 수 있습니다.

그리고 이것은 심각하게 당신이 달성 할 수있는 제한됩니다

binaryTotal = binaryInt + binaryFrac; 

부동 소수점에서 이렇게 심각한 제한이있을 것이다 -이 아닌 이상에서 상술 한 바와 같이 0.1을 대표하는 표현할 수없는 것을. 그렇기 때문에 이진수와 십진수가 혼합 된 답변을 얻을 수 있습니다.

이 문제를 해결하려면 숫자의 개별 비트를 살펴 봐야합니다. 솔루션의 전체적인 아이디어를 그대로 유지하려면 분수에서 2의 음수 (0.5, 0.25 등)를 빼고 계속 긍정적인지 테스트하고이를 기반으로 문자열을 작성하는 것이 가장 쉽습니다. 그런 다음 정수 부분에 대해 유사한 논리를 사용하십시오.

0

많은 문제 :

long double의 정수 부분이 심각 범위를 제한 추출 (int) 사용
  1. . 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); 사용 - 한 번 ppow() 반환 값의 정밀도> 손실은 몇 가지 값 (예 : 25)를 초과합니다. 또한 long double을 사용하는 기능을 가진 pow()을 사용하는 것이 이상합니다. 나는 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에서 별도의 intpart 발견, 그리고 2 나누기의 사용을 참조하십시오. 내 질문을 것 같아요 & x 않습니다 및 왜 2 곱하기 무엇입니까? x % 2가 0 일 때 끝에 '0'을 넣고 있습니까? 나는이 변환기 프로젝트가 C 코드를 작성하는 좋은 방법이 될 것이라고 생각했지만 지금은 이해할 수 없을 정도입니다. 감사합니다. – mike

+0

@mike'& x'는'x'의 주소입니다. 'modfl (lf, addr)'는'lf'를 반환되는 소수 부분과 전체 주소 부분으로 나눕니다.이 부분은 논의 된 주소에 저장됩니다. 함수 결과는 분수이며이 코드에서는 0.0 또는 0.5가됩니다. 2를 곱하면 0.0 또는 1.0이됩니다. "0"에 추가하면 인쇄를 위해 "0"또는 "1"이됩니다. 바라기를이 접근은 당신의 고유보다는 더 쉽다. 나는 그것이 당신의 이해를 넘어서는 것이라고 생각하지 않습니다. – chux

+0

아 좋아, 지금은 분명하다. 당신의 친절에 감사함을 전합니다. – mike

관련 문제