2013-05-02 3 views
0

아직 대학에서 C++로 강의를 시작했지만 첫 번째 문제가 있습니다. 우리의 작업은 IEEE 754 표준을 통해 포인트를 부동 ++ C에서 자체 제작 구조를 구현하기 위해 그 것이었다 :C++에서 자체 플로트 구조 만들기

당신이 float를 저장할 수있는 데이터 구조를 생성, 원시 바이트 표현하고 내부 표현을 읽어 s, e 및 m. union과 bit-field-struct의 조합을 사용하십시오. float 번호가 구조의 float 부분에 할당되고 raw 및 s/e/m 표현이 인쇄되는 프로그램을 작성하십시오. raw 및 m에 대해 16 진 출력을 사용하십시오.

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

union { 
    struct KFloat { 
     //Using bit fields for our self made float. s sign, e exponent, m mantissa 
     //It should be unsigned because we simply use 0 and 1 
     unsigned int s : 1, e : 8, m : 23; 
    }; 
    //One bit will be wasted for our '.' 
    char internal[33]; 
}; 

float calculateRealFloat(KFloat kfloat) { 
    if(kfloat.s == 0) { 
     return (1.0+kfloat.m)*pow(2.0, (kfloat.e-127.0)); 
    } else if (kfloat.s == 1) { 
     return (-1.0)*((1.0+kfloat.m)*pow(2.0, (kfloat.e-127.0))); 
    } 
    //Error case when s is bigger 1 
    return 0.0; 
} 

int main(void) { 
    KFloat kf_pos = {0, 128, 1.5707963705062866};//This should be Pi (rounded) aka 3.1415927 
    KFloat kf_neg = {1, 128, 1.5707963705062866};//Pi negative 

    float f_pos = calculateRealFloat(kf_pos); 
    float f_neg = calculateRealFloat(kf_neg); 

    printf("The positive float is %f or ",f_pos); 
    printf("%e\n", f_pos); 

    printf("The negative float is %f or ",f_neg); 
    printf("%e", f_neg); 
    return 0; 
} 

이 코드 첫 번째 오류는 가수가 절대적으로 잘못된 것을 명확하지만 난 방법이 문제를 해결하는 방법 아무 생각이 : 내가 지금까지 가지고 무엇

는 다음과 같습니다.

+2

가수는 정수 여야합니다. 가수에 대한 부동 소수점 값을 가진 IEEE에 대한 설명은 진실을 말하지 않습니다. – john

+0

귀하의 요구 사항은 구체적으로 '노동 조합'을 요구합니다. – Chad

+0

하지만 노조는 어떻게 구현해야합니까? 나는 원시적이고 내적인 represantation이 무엇을 의미하는지 모른다. – Jack

답변

2

작업을 다시 읽어주십시오 :

당신이 float를 저장할 수있는 데이터 구조를 만들기, 은 원시 바이트 표현 과의, 전자 및 m과 같은 내부 표현을 읽습니다.

union MyFloat 
{ 
    unsigned char rawByteDataRep[4]; 
    unsigned int rawDataRep; 
    float   floatRep; 
    struct{ // not checked this part just copied from you 
    unsigned s : 1; 
    unsigned e : 8; 
    unsigned m : 23; 
    }    componentesRep; 
} 

을하지만 조심 :

이 내가이 다음과 같은 방법을 할 것입니다 당신이 문자열

를 저장해야한다는 것을 의미하지 않습니다! 이 유니온 변환 패턴이 널리 사용되고 있다는 사실 외에도, C-Standard은 작성된 것보다 다른 unionmember를 읽으면 결과가 의 정의되지 않은 동작이라고 말합니다.

편집 : 는

void testMyfloat() 
{ 
    MyFloat mf; 
    mf.floatRep = 3.14; 
    printf("The float %f is assembled from sign %i magnitude 0x%08x and exponent %i and looks in memory like that 0x%08x.\n", 
     mf.floatRep, 
     (int)mf.componentesRep.s, 
     (unsigned int)mf.componentesRep.m, 
     (int)mf.componentesRep.e, 
     mf.componentesRep.rawDataRep); 

} 
+0

지수가 shoul에 서명되어 있다고 생각합니다. –

+0

C 표준에서는 동작이 완전히 정의되지 않았습니다. 마지막에 저장된 멤버가 아닌 다른 멤버가 액세스 될 때, 바이트는 새로운 타입으로 재 해석됩니다. 분명히 표현은 다소 구현에 달려 있습니다. 'unsigned int'를'uint32_t'로 변경하면,이 답변에 정의 된 공용체는 엔디안 및 비트 필드 순서로 인한 문제를 제외하고 많은 구현에서 작동 할 것입니다. –

+0

IEEE-754 2 진수의 저장된 지수는 항상 음수가 아닙니다. 실제 지수로 변환되면 저장된 값에서 127을 빼서 부호있는 값이됩니다 (32 비트 'float'의 경우). –

1

브루스 도슨은 소수점 표현과 연산 부동에 블로그 게시물의 우수한 시리즈를 가지고 UINT32 담당자를 추가했다. 이 주제에 대해 자세히 설명하는 이전 게시물에 대한 링크가 많이 포함 된 최신 시리즈는 here입니다.