2016-07-29 82 views
1

Ich mag würde verschiedenes n -Bit binäres Gleitkommaformate, die jeweils mit einem bestimmten e_max und e_min mit p Bit Genauigkeit emulieren. Ich möchte, dass diese Formate subnormale Zahlen nachahmen, die dem IEEE-754-Standard entsprechen.Subnormal Zahlen in verschiedenen Genauigkeiten mit MPFR

Natürlich hat mich meine Suche zur MPFR-Bibliothek geführt, die IEEE-754-konform ist und Subnormale mit der mpfr_subnormalize()-Funktion unterstützen kann. Ich bin jedoch mit der Verwendung von mpfr_set_emin() und mpfr_set_emax() in eine gewisse Verwirrung geraten, um eine subnormal-fähige Umgebung korrekt einzurichten. Ich werde IEEE doppelte Genauigkeit als Beispiel-Format verwenden, da dies das Beispiel in dem MPFR Handbuch ist:

http://mpfr.loria.fr/mpfr-current/mpfr.html#index-mpfr_005fsubnormalize

mpfr_set_default_prec (53); 
mpfr_set_emin (-1073); mpfr_set_emax (1024); 

Der obige Code aus dem MPFR Handbuch in dem obigen Link ist - beachten Sie, dass weder e_max noch e_min sind gleich den erwarteten Werten für double. Hier p wird auf 53, wie erwartet der double Typ, aber e_max wird auf 1024, anstatt den richtigen Wert von 1023 und e_min wird auf -1073; deutlich unter dem korrekten Wert von -1022. Ich verstehe, dass die Einstellung der Exponentengrenzen zu eng in Überlauf/Unterlauf in Zwischenberechnungen in MPFR führt, aber ich habe festgestellt, dass die Einstellung e_min genau ist entscheidend für die Gewährleistung der richtigen subnormalen Zahlen; zu hoch oder zu niedrig bewirkt, dass ein subnormales MPFR-Ergebnis (aktualisiert mit mprf_subnormalize()) von dem entsprechenden double Ergebnis abweicht.

Meine Frage ist, wie sollte man entscheiden, welche mpfr_set_emax() und (vor allem) mpfr_set_emin(), passieren Werte, um einen korrektes subnormaler Verhalten für ein Floating-Point-Format mit Exponenten Grenzen e_max und e_min zu gewährleisten? Es scheint keine detaillierte Dokumentation oder Diskussion zu diesem Thema zu geben.

Mit ganzem Dank,

James.

EDIT 30/07/16: Hier ist ein kleines Programm, das die Wahl der e_max und e_min für Zahlen einfacher Genauigkeit zeigt.

#include <iostream> 
#include <cmath> 
#include <float.h> 
#include <mpfr.h> 

using namespace std; 

int main (int argc, char *argv[]) { 
    cout.precision(120); 

    // Actual float emin and emax values don't work at all 
    //mpfr_set_emin (-126); 
    //mpfr_set_emin (127); 

    // Not quite 
    //mpfr_set_emin (-147); 
    //mpfr_set_emax (127); 

    // Not quite 
    //mpfr_set_emin (-149); 
    //mpfr_set_emax (127); 

    // These float emin and emax values work in subnormal range 
    mpfr_set_emin (-148); 
    mpfr_set_emax (127); 

    cout << "emin: " << mpfr_get_emin() << " emax: " << mpfr_get_emax() << endl; 

    float f = FLT_MIN; 
    for (int i = 0; i < 3; i++) f = nextafterf(f, INFINITY); 

    mpfr_t m; 
    mpfr_init2 (m, 24); 
    mpfr_set_flt (m, f, MPFR_RNDN); 

    for (int i = 0; i < 6; i++) { 
     f = nextafterf(f, 0); 
     mpfr_nextbelow(m); 
     cout << i << ": float: " << f << endl; 
     //cout << i << ": mpfr: " << mpfr_get_flt (m, MPFR_RNDN) << endl; 
     mpfr_subnormalize (m, 1, MPFR_RNDN); 
     cout << i << ": mpfr: " << mpfr_get_flt (m, MPFR_RNDN) << endl; 
    } 

    mpfr_clear (m); 
    return 0; 
} 
+0

Hmmm, reflektiert _e_min_ 'DBL_MIN' (min. Normalwert) oder' DBL_TRUE_MIN' (min. Subnormaler Wert)? – chux

+0

Off-1-1-Probleme treten häufig bei Exponentenbereichsspezifikationen für FP-Formate auf. Hängt vom Modell- und Zeichenformat 'x.xxx ... xxx' oder' .xxxx ... xxx' ab. – chux

+0

Ich folge nicht. Es ist nicht verwunderlich, dass das konfigurierte * e_min * das Verhalten von 'mpfr_subnormalize()' beeinflusst, wie für jede gegebene kleine Eingabe, die bestimmt, wie viele signifikante Bits der Genauigkeit es im Ergebnis geben wird, und tatsächlich, ob das Ergebnis ist subnormal (aus MPFR-Perspektive) überhaupt. Warum glauben Sie, dass Sie die MPFR-Exponentengrenzen auf andere Grenzen als die für das gewünschte Format festlegen würden? –

Antwort

1

Ich Kopieren meine Antwort, die ich auf Researchgate gab (mit einem Link zu der mpfr_subnormalize Dokumentation):

Es gibt verschiedene Konventionen Mantissen und die zugehörigen Exponenten auszudrücken. IEEE 754 wählt Signifikanden zwischen 1 und 2, während MPFR (wie die C-Sprache, siehe z. B. DBL_MAX_EXP) entscheidet, Signifikanden zwischen 1/2 und 1 zu berücksichtigen (aus praktischen Gründen im Zusammenhang mit Mehrfachpräzision). Zum Beispiel wird die Zahl 17 in IEEE 754 als 1.0001 · 2 und in MPFR als 0,10001 · 2 dargestellt.Wie Sie sehen können, bedeutet dies, dass Exponenten im MPFR um 1 gegenüber IEEE 754 erhöht werden, daher max = 1024 statt 1023 für doppelte Genauigkeit.

In Bezug auf die Wahl von e min für doppelte Genauigkeit, muss man in der Lage sein, um die Bedeutung von 2 -1074 = 0,1 · 2 -1073, so dass e min höchstens sein muss -1073 (wie in MPFR sind alle Zahlen normalisiert).

Wie dokumentiert, die mpfr_subnormalize Funktion der Auffassung, dass der subnormaler Exponent Bereich von e min min + PREC (x) bis e - 1, so dass zum Beispiel, müssen Sie e min = einstellen - 1073, IEEE doppelte Präzision zu emulieren.

+0

Danke Vincent; das hilft sehr. Nur um sicher zu sein, dass ich verstehe, IEEE-754-Exponenten sind um +1 in MPFR versetzt, und wenn ich ein * p * -Bit-Gleitkomma-Format wünschen würde, mit einem normalisierten Exponentenbereich untere Grenze von * e * , und korrekte Unternormale, würde ich 'mpfr_set_emin' mit * e - (p - 1) *? Prost. –

+1

@JamesTurner Grundsätzlich müssen Sie die am wenigsten positive Subnormale des Systems berücksichtigen. Wenn es 2^e ist, müssen Sie 'mpfr_set_emin' mit e + 1 aufrufen. Zum Beispiel ist für die doppelte Genauigkeit der am wenigsten positive Unternormale 2^(- 1022-53 + 1) = 2^(- 1074), so dass Sie 'mpfr_set_emin' mit -1074 + 1 = -1073 aufrufen müssen. Das ist emin-p + 1 mit emin, ausgedrückt in der MPFR/C-Konvention, oder emin-p + 2 mit emin, ausgedrückt in der IEEE-754-Binärkonvention. – vinc17