2017-11-20 4 views
-1

ich einen Gleitkommawert (float) einen festen Punkt umwandeln möge (s16: 15 oder s8: 23 oder andere Formate) Format in C.Float eines Fixed Point-Format-Konverter in C

Von der folgenden Code erwarte ich 0x00C0000 für eine Eingabe von 1,5 in s8.23 Fixpunktformat, aber ich bekomme stattdessen 0x3fC00000.

Versuchen wir eine komplizierte, für 0.69314718055995 erwarte ich 0x0058B90B aber stattdessen 0x3f317218.

Quelle Trusted: http://www.bytecraft.com/Fixed_Point_Converter

Beispielcode:

#include <stdio.h> 
#include <stdint.h> 
#include <inttypes.h> 

#define GetFixValue_32(f) (GetFixValue((f), 32, 8)) //8 bits of exponent 

uint64_t GetFixValue(long double f, unsigned bits, unsigned expBits) 
{ 
    long double fNorm; 
    int shift; 
    long long sign, exp, significand; 
    unsigned significandBits = bits - expBits - 1; // -1 for sign bit 

    if (f == 0.0) return 0; // getting the special case out of the way 

    // checking sign and beginning of normalization 
    if (f < 0) { sign = 1; fNorm = -f; } 
    else { sign = 0; fNorm = f; } 

    // getting the normalized form of f and track the exponent 
    shift = 0; 
    while(fNorm >= 2.0) { fNorm /= 2.0; shift++; } 
    while(fNorm < 1.0) { fNorm *= 2.0; shift--; } 
    fNorm = fNorm - 1.0; 

    // calculating the binary form (non-float) of the significand data 
    significand = fNorm * ((1LL<<significandBits) + 0.5f); 

    // getting the biased exponent 
    exp = shift + ((1<<(expBits-1)) - 1); // shift + bias 

    // returning the final answer 
    return (sign<<(bits-1)) | (exp<<(bits-expBits-1)) | significand; 
} 

int main(void) 
{ 
    float d = 1.5; 
    uint32_t di; 

    di = GetFixValue_32(d); 
    printf("double encoded: 0x%016" PRIx32 "\n", di); 
    return 0; 
} 

Was bin ich?

+0

'GetFixValue' sieht nicht so aus Code, Konvertiert Gleitkomma in Festkomma. Es sieht aus wie Code, der Gleitkomma in eine Gleitkomma-Codierung konvertiert. (Das heißt, es führt Fließkomma-Arithmetik durch, um die Bits zu bestimmen, die den Wert codieren.) Es trennt das Zeichen, normalisiert den Signifikanden und zählt die Exponenten und setzt dann die Bits für das Vorzeichen, den Exponenten und den Signifikanten in das Floating- Punktformat Also, was ist dieser Code? Es ist nichts, was Sie geschrieben haben, um Gleitkomma in Festkomma zu konvertieren. –

+0

Um 'float' in' s8: 23' zu konvertieren, verwenden Sie 'printf ("% 08X \ n ", (unsigniert) (int) (1.5f * powf (2,23)));' -> '00C00000' . – chux

+0

@chux Du bist ein Superheld! Danke;) – Shaown

Antwort

-1

Wenigstens dieser Teil scheint falsch

// getting the biased exponent 
exp = shift + ((1<<(expBits-1)) - 1); // shift + bias 

// returning the final answer 
return (sign<<(bits-1)) | (exp<<(bits-expBits-1)) | significand; 

Mit dem Eingang 1.5 shift 0 wird, so dass diese Zeile:

exp = shift + ((1<<(expBits-1)) - 1); // shift + bias 

geben 7F

und dieser Teil der return-Anweisung

(exp<<(bits-expBits-1)) 
daher

wird sich als 3F800000

Ende Daher kann man nie 00C00000 für den Eingang erreichen 1,5

Ich bin nicht sicher, aber vielleicht möchten Sie

exp = shift + 1;