$DOUBLE (ObjectScript)
構文
$DOUBLE(num)
引数
引数 | 説明 |
---|---|
num | 変換される数値。文字列 “NAN” と “INF” (およびそれらの異形) も指定できます。 |
説明
$DOUBLE は、IEEE 倍精度 (64 ビット) バイナリ浮動小数点データ型に変換された数値 (これは、インターシステムズの $DOUBLE 形式としても知られ、DOUBLE および DOUBLE PRECISION SQL データ型に対応します) を返します。これは、$DECIMAL 関数で実行される処理の逆です。
$DOUBLE 形式の数値には 20 桁まで格納できます。num が 20 桁より多い場合、$DOUBLE は、小数部を適切な桁数に丸めます。num の整数部の有効桁が 20 より多い場合、$DOUBLE は、整数部を 20 桁に丸め、追加の桁をゼロで表します。
InterSystems IRIS 浮動小数点データ型 ("1E128" など) がサポートする最小/最大範囲を超える InterSystems IRIS 数値文字列リテラルは、自動的に IEEE 倍精度浮動小数点数に変換されます。この変換は数値リテラルに対してのみ実行され、算術演算の結果に対しては行われません。%SYSTEM.ProcessOpens in a new tab クラスの TruncateOverflow()Opens in a new tab メソッドを使用すると、自動変換をプロセスごとに制御できます。システム全体の既定の動作は、Config.MiscellaneousOpens in a new tab クラスの TruncateOverflowOpens in a new tab プロパティで設定できます。
num 値は、数字または数値文字列で指定できます。$DOUBLE 変換の前に、キャノニック形式 (先頭と末尾にあるゼロを削除し、複数のプラス符号とマイナス符号に解決されるなど) に解決されます。数値でない文字列を num に指定すると 0 が返されます。混合数値文字列 ("7dwarves" または "7.5.4" など) を num に指定すると、数値でない文字が初めて現れた箇所で入力値が切り捨てられ、その後、数値部が変換されます。JSON 配列または JSON オブジェクトに指定される $DOUBLE 数値は、異なる検証規則と変換規則に従います。
等値比較と混合算術
$DOUBLE で生成される数値は、正確には小数点以下の桁数と一致しないバイナリ表現に変換されるため、$DOUBLE 値と10 進数値の間での同等比較は予期しない結果を生じさせる場合があり、一般的にはこれを回避する必要があります。"インターシステムズ・アプリケーションでの数値の計算" を参照してください。
整数除算
特定の値の場合、10 進および $DOUBLE 形式の数値は、異なる整数除算結果を生成します。次に例を示します。
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
リストの圧縮
ListFormat は、$DOUBLE 形式の数値を、$LIST エンコードされた文字列に格納する際に圧縮するかどうかを制御します。既定では、圧縮されません。圧縮された形式は、InterSystems IRIS によって自動的に処理されます。圧縮された形式がサポートされるかどうかを確認せずに、Java や C# などの外部クライアントに圧縮されたリストを渡さないでください。
%SYSTEM.ProcessOpens in a new tab クラスの ListFormat()Opens in a new tab メソッドを使用すると、プロセスごとの動作を制御できます。
Config.MiscellaneousOpens in a new tab クラスの ListFormatOpens in a new tab プロパティを設定するか、InterSystems IRIS の管理ポータルで [システム管理] から [構成]、[追加の設定]、[互換性] を選択して、システム全体の既定の動作を設定できます。
INF と NAN
IEEE 標準に従って、$DOUBLE は、文字列 INF (無限大) および NAN (非数値) を返します。INF は、正の数でも負の数でもかまいません(INF、-INF)。NAN は常に符号なしです。これらは有効な IEEE 返り値ですが、実際の数ではありません。
入力値としての INF と NAN
$DOUBLE を INF と NAN に返すには、num 入力値と同等の文字列を指定します。これらの入力値は大文字と小文字を区別せず、先頭にプラス符号とマイナス符号を使用できます (INF は符号を解決し、NAN は符号を無視します)。NAN を返すには、“NAN”、“sNAN”、“+NAN”、“-NAN” を指定します。INF を返すには、“INF”、“+INF”、“Infinity” を指定します。-INF を返すには、“-INF” と “+-INF” を指定します。
IEEEError
IEEEError は、解決できない数値変換に対する $DOUBLE の応答方法を制御します。IEEEError が 0 に設定されている場合、$DOUBLE は変換を解決できないときに INF と NAN を返します。IEEEError が 1 に設定されている場合、$DOUBLE は変換を解決できないときに標準の InterSystems IRIS エラー・コードを生成します。既定値は 1 です。
%SYSTEM.ProcessOpens in a new tab クラスの IEEEError()Opens in a new tab メソッドを使用すると、プロセスごとの動作を制御できます。
Config.MiscellaneousOpens in a new tab クラスの IEEEErrorOpens in a new tab プロパティを設定するか、InterSystems IRIS の管理ポータルで [システム管理] から [構成]、[追加の設定]、[互換性] を選択して、システム全体の既定の動作を設定できます。
INF と NAN の返り値
極端に大きな数字を指定したり、解決できない算術演算を指定すると、$DOUBLE は INF と NAN を返します。これらの値が返されるのは、IEEEError が INF および NAN を返すように設定されている場合のみです。
極端に大きい浮動小数点数はサポートされません。$DOUBLE のバイナリ浮動小数点数でサポートされる最大値は 1.7976931348623158079e308 です。$DOUBLE のバイナリ浮動小数点数でサポートされる最小値は 1.0E-323 です。これより小さい num 値は 0 を返します。
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 を扱います。
詳細は、"インターシステムズ・アプリケーションでの数値の計算" を参照してください。
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)
JSON 数値リテラル
数値リテラルの JSON 検証については、SET コマンドで説明しています。JSON 配列または JSON オブジェクトで指定された $DOUBLE 数値リテラルは、以下の追加規則に従います。
-
INF 値、-INF 値、および NAN 値は、JSON 構造に格納できますが、%ToJSON() によって返すことはできません。これを実行しようとすると、以下の例に示すような、<ILLEGAL VALUE> エラーが返されます。
SET jary=[123,($DOUBLE("INF"))] // executes successfully WRITE jary.%ToJSON() // fails with <ILLEGAL VALUE> error
-
$DOUBLE(-0) は JSON 構造に -0.0 として格納されます。$DOUBLE(0) または $DOUBLE(+0) は JSON 構造に 0.0 として格納されます。以下に例を示します。
SET jary=[0,-0,($DOUBLE(0)),($DOUBLE(-0))] WRITE jary.%ToJSON() // returns [0,-0,0.0,-0.0]
例
以下の例は、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" }