Your Browser is not longer supported

Please use Google Chrome, Mozilla Firefox or Microsoft Edge to view the page correctly
Loading...

{{viewport.spaceProperty.prod}}

Gleitkommazahlen

&pagelevel(4)&pagelevel

Die Java-Datentypen float und double sind Gleitkomma-Datentypen, die im JNI durch die C-Datentypen jfloat und jdouble dargestellt werden.

Diese Datentypen sind formal kompatibel zu den C-Datentypen float und double. Da aber ihre Darstellung im IEEE-Format (statt /390-Format) erfolgt, können sie ohne Vorkehrungen nicht in C verwendet werden.

Neben expliziten Konvertierungsmöglichkeiten stehen für die Unterstützung des IEEE-Formates entsprechende Compiler- und Laufzeitsystem-Erweiterungen bereit, die es erlauben, direkt mit diesem Zahlenformat in C zu arbeiten.

Explizite Konvertierung

Für die explizite Konvertierung zwischen Gleitkommazahlen im IEEE-Format und im /390-Format stehen einige Funktionen zur Verfügung. Diese sind deklariert in der Header-Datei ieee_390.h, die Bestandteil der CRTE-Distribution ist. Diese Konvertierungsfunktion sind im Handbuch „CRTE“ [3] beschrieben.



Beispiel

Das folgende Beispiel zeigt die Verwendung in einer nativen Methode, die arithmetische Manipulationen an einer Gleitkommazahl vornimmt. Auf Java-Seite sei die Methode deklariert als:

public native double manipulate(double arg);

Das zugehörige C-Programm könnte folgendermaßen aussehen:

#include <jni.h>
#include ".....h" // javah generierter Header
#include <ieee_390.h>
JNIEXPORT jdouble JNICALL
Java_..._manipulate(JNIEnv *env, jobject jthis, jdouble num);
{
  double result, arg;
  arg = ieee2double(num);
  result = (arg < 1.7)? arg * 3.4 : arg - 1.0;
  return double2ieee(result);
}

Es sei noch darauf hingewiesen, dass im obigen Beispielcode noch jegliche Fehlerbehandlung für die möglichen Konvertierungsfehler fehlt.

IEEE-Gleitkommazahlen im C-Code

Der C/C++-Compiler ab der Version V3.0B bietet die Möglichkeit, alternativ zum /390-Format für Gleitkommazahlen, auch Code für das IEEE-Format zu erzeugen. Die über die Compiler-Option -Kieee_floats gesteuerte Einstellung gilt für die gesamte CompilierungsEinheit (Source-Datei).

Diese Option hat nur eine Wirkung auf Gleitkomma-Konstanten im Source-Code sowie Arithmetik, Typumwandlung oder Vergleich von Gleitkommazahlen. Sie hat keinen Einfluss auf die Übergabe solcher Daten an andere Funktionen oder einfache Zuweisungen.

Das Setzen dieser Option bewirkt außerdem implizit, dass C-Library-Funktionen mit Gleitkomma-Argumenten und/oder Gleitkomma-Ergebnis in einer Variante für IEEE-Arithmetik benutzt werden kann.

Die gesamte Arithmetik wird über entsprechende Emulationsroutinen abgewickelt. Dies gilt auch für SQ-Maschinen, solange über Asstran noch keine Generierung von native Code für die entsprechenden Befehle möglich ist. Dies geht selbstverständlich erheblich zu Lasten der Performance. C-Programme, die intensiv Gleitkomma-Arithmetik nutzen, sollten daher nicht in diesem Modus arbeiten.



Beispiel

Das vorherige Beispiel könnte dann folgendermaßen realisiert sein:

#include <jni.h>
#include ".....h" // javah generierter Header

JNIEXPORT jdouble JNICALL 
Java_..._manipulate(JNIEnv *env, jobject jthis, jdouble num) 
{ 
    return (num < 1.7)? num * 3.4 : num - 1.0;
}

Die Übersetzung muss mit der C-Compiler-Option -Kieee_floats erfolgt sein.

IEEE-Gleitkommazahlen im C-Laufzeitsystem

Das C-Laufzeitsystem bietet neben den in ieee_390.h deklarierten Konvertierungsroutinen alle wesentlichen XPG4-Funktionen, die mit Gleitkommazahlen umgehen, in einer Variante für IEEE-Arithmetik an. Beim Setzen der Compiler-Option für IEEE-Nutzung werden normalerweise automatisch die entsprechenden Library-Funktionen benutzt, ohne dass der Anwender dafür etwas tun muss. Für den Mischbetrieb können Sie das Verhalten auch verändern (siehe Handbuch „CRTE“ [3]).



Beispiel

Das folgende Beispiel zeigt die Verwendung der IEEE-Version der C-Funktion tanh in einer native Methode zur Ermittlung des Tangens hyperbolicus in einer Java-Klasse. Auf Java-Seite sei die Methode deklariert als:

public native double tanhyp(double arg);

Das zugehörige C-Programm könnte folgendermaßen aussehen:

#include <math.h>
#include <jni.h
#include ".....h" // javah generierter Header 

JNIEXPORT jdouble JNICALL 

Java_..._tanhyp(JNIEnv *env, jobject jthis, jdouble num) 
{ 
    //printf("tan_hyp called with: %e\n",num); 
    return tanh(num); 
}

In dieser Form muss die Übersetzung mit der C-Compiler-Option -Kieee_floats erfolgt sein.