cc [ flag ... ] file ... -lsunmath -lm [ library ... ] #include <sunmath.h>
enum convert_external_arch_t = { convert_external_sparc, convert_external_pc, convert_external_vax, convert_external_vaxg, convert_external_s370, convert_external_cray }; enum convert_external_type_t = { convert_external_signed, convert_external_unsigned, convert_external_float }; enum convert_external_rounding_t = { convert_external_common = -1, convert_external_biased = -2, convert_external_away = -3 }; typedef struct { enum convert_external_arch_t arch ; /* 書式のアーキテクチャー */ enum convert_external_type_t type ; /* 書式の型 */ int size ; /* 書式サイズ、バイト (8 ビット) 数で */ } convert_external_t ;
fp_exception_field_type convert_external(const char *src_p, convert_external_t src_format, char *dst_p, convert_external_t dst_format, int rounding, int n);
fp_exception_field_type convert_external_(const char *src_p, const convert_external_t *src_format_p, char *dst_p, const convert_external_t *dst_format_p, const int *rounding_p, const int *n_p);
convert_external() は、C プログラムで、SPARC 以外のシステム上のバイナリデータと SPARC バイナリデータとを変換する際に使用されます。データは、符号付き整数、符号なし整数、または浮動小数点データです。convert_external_() は、すべてのパラメータが参照呼び出しである Fortran プログラム (CALL CONVERT_EXTERNAL(...)) でも同じ目的で使用されます。
convert_external_t 型は、サポートされている形式で記述されます。アーキテクチャーごとに、サイズが 1、2、4、8、16 バイトの符号付き整数と符号なし整数、およびサイズが 4、8、10、12、16 バイトの浮動小数点型がサポートされています。変換元または変換先に不適切なサイズが指定された場合、変換は行われず、(1<<fp_division) が返されます。それ以外の場合、例外は発生しません。
サポートされているアーキテクチャーと形式には次が含まれます:
external_t endian- float*4 float*8 float*10 float*12 float*16 architec- ness format format format format format ture sparc big IEEE IEEE none MC68881 IEEE single double extended quad pc little IEEE IEEE i80x87 i80960KB IEEE single double extended extended quad vax little VAX F VAX D none none VAX H vaxg little VAX F VAX G none none VAX H s370 big S/370 S/370 none none S/370 single double extended cray big none Cray-1 none none Cray-1 single double
MC68000 と SPARC の形式は同じビッグエンディアン形式で、Intel PC 8086/8087、80x86/7、80486 の形式は同じリトルエンディアン形式です。表のエントリ「なし」は、サイズが不適切で、変換が行われないことを表します。「IEEE 4 倍精度」は、IEEE 単精度および倍精度を 15 の指数ビット、1 つの暗黙的仮数ビット、112 の暗黙的仮数ビットを含む形式にビッグまたはリトルエンディアン拡張することを示します。
excep = convert_external(src_p, src_format, dst_p, dst_format, rounding, n);
関数値は、変換中に発生したすべての例外の累積です。個別に例外を検出することが重要である場合は、一度に 1 つのデータ項目だけが変換されるように n を 1 にしてください。
連続配列として格納された変換対象データへのポインタ。整列の必要がないことを強調するために、ポインタは char * と宣言されています。ただし、同じプログラムによる今後の処理のために、SPARC 形式に変換されるデータは適切に整列するようにしてください。
連続配列として格納された変換済みデータへのポインタ。
変換元データの形式に関する記述。
変換先データの形式に関する記述。
変換先データに適用される丸めモード。
変換対象データ項目の数。
次の丸めを選択できます。1 番目の目的は、ほぼすべてのアプリケーションの要求を満たすことです。
整数と符号なしの変換先形式をゼロ方向に丸めます (2.9 は 2 に、-2.9 は -2 に丸める)。IEEE 浮動小数点の変換先をもっとも近い非バイアス値に丸めます。VAX 浮動小数点の変換先をもっとも近いバイアス値に丸めます。IBM 370 と Cray の浮動小数点の変換先をゼロ方向に丸めます。
もっとも近いバイアス値に丸めます (整数の変換先の場合、1.5 は 2 に、2.5 は 3 に丸める)。
ゼロと逆方向に丸めます (整数の変換先の場合、2.1 は 3、-2.1 は -3 に丸める)。
IEEE 754 で規定されているモードの 1 つで丸めます。
変換後に、(excep & (1 << fp_invalid)) != 0 の場合、1 つ以上の無効な例外が発生します。その他の例外も、これと同様に定義されています。
入力引数が IEEE シグナリング NaN または VAX の予約済みオペランドだったか、または入力引数が無限大で、かつ変換先が整数型、符号なし型、または無限大表記なしの浮動小数点型であったことを示します。
入力引数が有限数で大きかったが、通常の丸め誤差だけでは変換先の形式で表示できなかったことを示します。変換先の形式が整数または符号なし型の場合、fp_overflow は整数オーバーフローを表します。
入力引数が有限数で小さかったが、通常の丸め誤差だけでは変換先の形式で表示できなかったことを示します。これは、変換先が浮動小数点型の場合にしか発生しません。
入力引数は有限数だったが、変換先の形式で正確に表示できなかったことを示します。
変換元または変換先の形式がサポートされていません。変換は行われません。
外部データを SPARC 形式に変換し、SPARC 上で処理したあとに、外部形式に戻す場合は、SPARC 上の変換と処理で例外が発生しなくても、外部システム上でデータを完全に処理した場合と同じ結果となることはほとんどありません。
次のコードは、外部システム上の Fortran でバイナリ浮動小数点データを生成する典型的な方法を示しています。
REAL A(100) WRITE(9) A
上記のバイナリデータファイルが Cray 上のテープで作成され、SPARC システム上で読み込まれたとします。IEEE 倍精度浮動小数点形式に変換するときに、バイアスされた丸めを使用する方法は次のとおりです。
#include <sunmath.h> char datasrc[800]; double datadest[100]; fp_exception_field_type excep; int rounding; int i; convert_external_t src, dest; /* read the Cray data into the array datasrc somehow, then ... */ src.arch = convert_external_cray; src.type = convert_external_float; src.size = 8; dest.arch = convert_external_sparc; dest.type = convert_external_float; dest.size = 8; rounding = convert_external_biased; excep = convert_external((char *) datasrc, src, (char *) datadest, dest, rounding, 100); /* * usually you are not interested in inexact exceptions * and you'd do this */ excep &= ~(1 << fp_inexact); /* * other exceptions are possible in this example - after the fact, * you can find out where they happened this way */ if (excep != 0) for (i = 0 ; i < 100 ; i++) { excep = convert_external((char *)&datasrc[8 * i], src, (char *)&datadest[i], dest, rounding, 1); if (excep != 0) { /* do something specific about datadest[i] */ } }
SPARC プログラムで作成したデータを IBM PC に読み込ませるとします。変換する方法は次のとおりです。
#include <floatingpoint.h> REAL*4 datasrc(100) REAL*4 datadest(100) INTEGER excep, convert_external, round INTEGER src(4), dest(4) c create datasrc array somehow, then ... src(1) = convert_external_sparc src(2) = convert_external_float src(3) = 4 dest(1) = convert_external_pc dest(2) = convert_external_float dest(3) = 4 round = convert_external_common excep = convert_external(datasrc, src, datadest, dest, round, 100); c The only exception that can arise is fp_invalid, c by converting a signaling NaN. c Now write the data out in a file that an IBM PC can read
次の属性については、attributes(5) を参照してください。
|
外部システムからテープを読み込む方法については、 dd (1M) 、任意のデータ構造をマシンに依存した方法で書式化する方法については、 xdr (3NSL) を参照してください。
変換元データをすべての入力を正確に保持するのに十分な大きさの内部形式に変換してから、内部データを変換先の形式に変換することで、一度に 1 つずつ変換が実行されます。したがって、変換元と変換先の形式は自由に組み合わせることができますが、ある特定の形式から別の形式に変換するように作成されたプログラムを使用する場合ほど効率性はありません。