Ich habe eine Frage über die pack754()
Funktion definiert in Section 7.4 of Beej's Guide to Network Programming.Warum multiplizieren wir den normierten Bruch mit 0,5, um den Signifikanden in der IEEE 754-Darstellung zu erhalten?
Diese Funktion wandelt eine Gleitkommazahl f
in seine IEEE 754-Darstellung in dem bits
die Gesamtzahl von Bits ist, die Zahl zu repräsentieren und expbits
ist die Anzahl von Bits verwendet nur den Exponenten darzustellen.
Ich bin besorgt darüber, mit einfacher Genauigkeit Zahlen schwimmend nur, so dass für diese Frage, bits
als 32
angegeben und expbits
als 8
angegeben. Dies bedeutet, dass 23
Bits verwendet werden, um den Signifikanden zu speichern (weil ein Bit das Vorzeichenbit ist).
Meine Frage bezieht sich auf diese Codezeile.
significand = fnorm * ((1LL<<significandbits) + 0.5f);
Was ist die Rolle von + 0.5f
in diesem Code?
Hier ist ein vollständiger Code, der diese Funktion verwendet.
#include <stdio.h>
#include <stdint.h> // defines uintN_t types
#include <inttypes.h> // defines PRIx macros
uint64_t pack754(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; // get this special case out of the way
// check sign and begin normalization
if (f < 0) { sign = 1; fnorm = -f; }
else { sign = 0; fnorm = f; }
// get 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;
// calculate the binary form (non-float) of the significand data
significand = fnorm * ((1LL<<significandbits) + 0.5f);
// get the biased exponent
exp = shift + ((1<<(expbits-1)) - 1); // shift + bias
// return the final answer
return (sign<<(bits-1)) | (exp<<(bits-expbits-1)) | significand;
}
int main(void)
{
float f = 3.1415926;
uint32_t fi;
printf("float f: %.7f\n", f);
fi = pack754(f, 32, 8);
printf("float encoded: 0x%08" PRIx32 "\n", fi);
return 0;
}
Welchen Zweck erfüllt + 0.5f
in diesem Code?
Irgendetwas sagt mir, dass Sie diese Zeile nicht korrekt kopiert haben. Insbesondere denke ich, dass Sie einen zusätzlichen Satz von Klammern hinzugefügt haben. – user3386109
@ user3386109 Der referenzierte Link hat den gleichen Kommentar und den gleichen Code 'significand = fnorm * ((1LL << significandbits) + 0.5f);' und die gleichen Typen. Stimme zu, ob es besser funktionieren würde als 'significand = fnorm * (1LL << significandbits) + 0.5f; '. – chux