説明
$DOUBLE は、IEEE 倍精度 (64 ビット) バイナリ浮動小数点データ型に変換された数値を返します。この型の浮動小数点数には 20 桁まで格納できます。num が 20 桁より多い場合、$DOUBLE は、小数部を適切な桁数に丸めます。num の整数部の有効桁が 20 より多い場合、$DOUBLE は、整数部を 20 桁に丸め、追加の桁をゼロで表します。
$DOUBLE は、InterSystems IRIS 浮動小数点数を IEEE 倍精度浮動小数点数に変換します。$DECIMAL は逆の処理を実行します。IEEE 倍精度浮動小数点数を標準の InterSystems IRIS 浮動小数点数 (NUMERIC データ型) に変換します。
$DOUBLE は、IEEE 倍精度 (64 ビット) バイナリ浮動小数点標準に一致する浮動小数点数値を生成します。これは主に、このデータ型標準を使用するアプリケーションとの互換性があり、置換することを目的としています。IEEE 浮動小数点数は、バイナリ表現で表されます。これらの精度は 53 バイナリ・ビットで、これは 15.95 小数桁数に相当します (バイナリ表現は正確に小数と一致するものではありません)。
IEEE 浮動小数点数は、標準の InterSystems IRIS 浮動小数点数よりも大きい最小/最大値の範囲をとることができます。ただし、標準の InterSystems IRIS 浮動小数点数は、より大きい精度になります。多くの場合、標準の InterSystems IRIS 浮動小数点数が推奨されます。
num 値は、数字または数値文字列で指定できます。$DOUBLE 変換の前に、キャノニック形式 (先頭と末尾にあるゼロを削除し、複数のプラス符号とマイナス符号に解決されるなど) に解決されます。数値でない文字列を num に指定すると 0 が返されます。混合数値文字列 ("7dwarves" または "7.5.4" など) を num に指定すると、数値でない文字が初めて現れた箇所で入力値が切り捨てられ、その後、数値部が変換されます。JSON 配列または JSON オブジェクトに指定される $DOUBLE 数値は、異なる検証規則と変換規則に従います。
InterSystems SQL データ型の DOUBLE と DOUBLE PRECISION は、IEEE 浮動小数点数を表します。NUMERIC データ型は、標準 InterSystems IRIS 浮動小数点数を表します。
等値比較と混合算術
$DOUBLE で生成される数値は、正確には小数点以下の桁数と一致しないバイナリ表現に変換されるため、$DOUBLE 値と標準 InterSystems IRIS 浮動小数点数値の間での同等比較は予期しない結果を生じさせる場合があり、一般的にはこれを回避する必要があります。$DOUBLE 値と標準 InterSystems IRIS 浮動小数点数値の間では、丸めを行わず、正確に比較を行います。
1 つの $DOUBLE 値と 1 つ以上の標準の InterSystems IRIS 数値を含む混合算術演算は、$DOUBLE 値を返します。混合算術では、InterSystems IRIS は、算術演算を実行する前に、すべての数値を $DOUBLE 値に自動的に変換します。$DOUBLE 数値表現から、またはこの数値表現への変換、および数値表現間の比較は、InterSystems IRIS が処理します。したがって、すべてのプラットフォームで同じ処理となります。ただし、$DOUBLE 値を含む算術演算は、基盤となるオペレーティング・システムによって制御されるため、プラットフォーム間で異なる場合があります。IEEE 倍精度数を含む算術演算の詳細は、“サーバ側プログラミングの入門ガイド” の付録 "インターシステムズ・アプリケーションでの数値の計算" を参照してください。
整数除算
特定の値の場合、InterSystems IRIS の 10 進数の浮動小数点数および IEEE 倍精度数は、異なる整数除算結果を生成します。次に例を示します。
WRITE !,"Divide operations:"
WRITE !,"IRIS /: ",4.1/.01 // 410
WRITE !,"Double /: ",$DOUBLE(4.1)/.01 // 410
WRITE !,"Integer divide operations:"
WRITE !,"IRIS \: ",4.1\.01 // 410
WRITE !,"Double \: ",$DOUBLE(4.1)\.01 // 409
INF と NAN
IEEE 標準に従って、$DOUBLE は、文字列 INF (無限大) および NAN (非数値) を返します。INF は、正の数でも負の数でもかまいません(INF、-INF)。NAN は常に符号なしです。これらは有効な IEEE 返り値ですが、実際の数ではありません。
INF と NAN の返り値
極端に大きな数字を指定したり、解決できない算術演算を指定すると、$DOUBLE は INF と NAN を返します。これらの値が返されるのは、IEEEError が INF および NAN を返すように設定されている場合のみです。
極端に大きい浮動小数点数はサポートされません。$DOUBLE のバイナリ浮動小数点数でサポートされる最大値は 1.7976931348623158079e308 です。$DOUBLE のバイナリ浮動小数点数でサポートされる最小値は 1.0E-323 です。これより小さい num 値は 0 を返します。
Note:
InterSystems IRIS の 10 進数の浮動小数点数でサポートされる最大値は 9.223372036854775807e145 です。InterSystems IRIS の 10 進数の浮動小数点数でサポートされる最小値は 2.2250738585072013831e-308 (標準) または 4.9406564584124654417e-324 (非正規化) のいずれかです。
以下のテーブルは、返り値または解決できない算術演算によって生成されたエラーを示します。
入力値 |
IEEEError=0 |
IEEEError=1 |
> 1.0E308 |
INF |
<MAXNUMBER> |
< 1.0E-323 |
0 |
0 |
1/$DOUBLE(0) |
INF |
<DIVIDE> |
1/$DOUBLE(-0) |
–INF |
<DIVIDE> |
$DOUBLE(1)/0 |
INF |
<DIVIDE> |
$DOUBLE(0)/0 |
NAN |
<ILLEGAL VALUE> |
$ZLOG($DOUBLE(0)) |
–INF |
<DIVIDE> |
INF と NAN の比較
INF は数値として比較できます。例えば、INF = INF、INF '= –INF、–INF = –INF、INF > –INF となります。
NAN は数値として比較できません。NAN (非数値) は数値演算子を使用して有意義に比較できないため、$DOUBLE("NAN") と別の $DOUBLE("NAN") を比較しようとする InterSystems IRIS 演算 (より大きい、等しい、より小さいなど) は失敗します。NAN <= または >= での比較は特殊な場合です。これは、“サーバ側プログラミングの入門ガイド” の付録 "インターシステムズ・アプリケーションでの数値の計算" で説明されています。
$LISTSAME は $DOUBLE(“NAN”) リスト要素を別の $DOUBLE(“NAN”) リスト要素と同一と見なします。
InterSystems IRIS は、異なる NAN 表現 (NAN、sNAN など) を区別しません。NAN のバイナリ表現に関係なく、すべての NAN を同一と見なします。
$ISVALIDNUM、$INUMBER、および $FNUMBER
これらの ObjectScript 関数は、$DOUBLE 数をサポートしています。
$ISVALIDNUM は、INF および NAN をサポートしています。これらの文字列は数字ではありませんが、$ISVALIDNUM 関数は、これらの値に対して数字として 1 を返します。$DOUBLE が非数値文字列 ($DOUBLE("") など) で指定されている場合、InterSystems IRIS は 0 の値を返します。このため、0 は数字なので、$ISVALIDNUM($DOUBLE("")) は 1 を返します。
$INUMBER および $FNUMBER は、$DOUBLE 値をサポートする “D” 形式オプションを提供します。$INUMBER は、数値を IEEE 浮動小数点数に変換します。$FNUMBER “D” のサポートは、INF および NAN の大文字と小文字の変換を含み、$DOUBLE(-0) が 0 と -0 のどちらを返すかを選択します。
演算子を使用した INF と NAN
INF と NAN に対して算術演算子と論理演算子を実行できます。INF と NAN と共に演算子を使用することはお勧めしません。このような演算を実行すると、以下のような結果になります。
算術演算子 :
加算 |
減算 |
乗算 |
除算 (/、\、または # 演算子) |
NAN+NAN=NAN |
NAN-NAN=NAN |
NAN*NAN=NAN |
NAN/NAN=NAN |
NAN+INF=NAN |
NAN-INF=NAN |
NAN*INF=NAN |
NAN/INF=NAN |
|
INF-NAN=NAN |
|
INF/NAN=NAN |
INF+INF=INF |
INF-INF=NAN |
INF*INF=INF |
INF/INF=NAN |
論理演算子 :
等しい (=) |
NAN |
INF |
NAN |
0 |
0 |
INF |
0 |
1 |
より小さい (<)/より大きい (>) |
NAN |
INF |
NAN |
0 |
0 |
INF |
0 |
0 |
パターン・マッチングや連結演算子などの他の演算子は、3 文字のアルファベット文字列として NAN と INF を扱います。
IEEE 倍精度数を含む演算の詳細は、"サーバ側プログラミングの入門ガイド" の付録 “インターシステムズ・アプリケーションでの数値の計算” を参照してください。
INF と NAN の例
以下の例に示すように、数値が使用可能な精度を超えた場合、$DOUBLE は INF 値 (負数に対しては -INF) を返します。
SET rtn=##class(%SYSTEM.Process).IEEEError(0)
SET x=$DOUBLE(1.2e300)
WRITE !,"Double: ",x
WRITE !,"Is number? ",$ISVALIDNUM(x)
SET y= $DOUBLE(x*x)
WRITE !,"Double squared: ",y
WRITE !,"Is number? ",$ISVALIDNUM(y)
数値が無効な場合、$DOUBLE は NAN (非数値) 値を返します。例えば、以下の例に示すように、算術式に 2 つの INF 値が含まれる場合です (1 つの INF 値を含む算術式は INF を返します)。
SET rtn=##class(%SYSTEM.Process).IEEEError(0)
SET x=$DOUBLE(1.2e500)
WRITE !,"Double: ",x
WRITE !,"Is number? ",$ISVALIDNUM(x)
SET y= $DOUBLE(x-x)
WRITE !,"Double INF minus INF: ",y
WRITE !,"Is number? ",$ISVALIDNUM(y)
例
以下の例は、20 桁の浮動小数点数を返します。
WRITE !,$DOUBLE(999.12345678987654321)
WRITE !,$DOUBLE(.99912345678987654321)
WRITE !,$DOUBLE(999123456789.87654321)
以下の例では、pi の値が $DOUBLE 値と標準の InterSystems IRIS 数値で返されます。この例では、$DOUBLE 数と標準 InterSystems IRIS 数の間で等値演算を行うべきでないこと、および標準 InterSystems IRIS 数について返される桁数の方が大きくなることを示しています。
SET x=$ZPI
SET y=$DOUBLE($ZPI)
IF x=y { WRITE !,"Same" }
ELSE { WRITE !,"Different"
WRITE !,"standard: ",x
WRITE !,"IEEE float: ",y }
以下の例では、浮動小数点数は、同じ値の数値文字列と同等である必要がないことを示しています。
SET x=123.4567891234560
SET y=123.4567891234567
IF x=$DOUBLE(x) { WRITE !,"Same" }
ELSE { WRITE !,"Different" }
IF y=$DOUBLE(y) { WRITE !,"Same" }
ELSE { WRITE !,"Different" }
SET x=1234567891234560
SET y=1234567891234567
IF x=$DOUBLE(x) { WRITE !,"Same" }
ELSE { WRITE !,"Different" }
IF y=$DOUBLE(y) { WRITE !,"Same" }
ELSE { WRITE !,"Different" }