式中の算術演算子
算術演算子を使う場合、式の結果は、オペランドの値に 演算子を適用することで導き出された数値となります。
式の結果は NULL になる可能性があります。 いずれかのオペランドが NULL 値を持つ場合、式の結果は NULL となります。 ストリングに算術演算子 (意味のない単項正符号を除く) を
適用してはなりません。 例えば、 USER+2 は無効です。 日時値に乗算および除算の演算子を適用してはなりません。
日時値は加算と減算しかできません。
前置演算子 + (単項プラス )は、そのオペランドを変更しません。 接頭演算子 - (単項減算 )は、ゼロ以外の非十進浮動小数点演算子の符号を反転させます。 接頭演算子 - (単項減算 )は、ゼロや特殊値を含むすべての10進浮動小数点演算子の符号を反転させます。つまり、符号付きおよび符号なしの NaNs、プラスおよびマイナス無限大です。 A のデータ型が小整数である場合、 -A のデータ型は大整数です。 接頭演算子の後のトークンの最初の文字は、正符号または負符号であってはなりません。
中置演算子は、加算 (+)、減算 (-)、乗算 (*)、および除算 (/) を指定します。 除算の2番目のオペランドの値はゼロであってはなりません。
2 つの整数オペランドを指定した算術演算
算術演算子の両方のオペランドが整数の場合、演算は 2 進数で行われます。 結果は、いずれか一方 (または両方) のオペランドが 64 ビット整数でない限り、長精度整数になります。一方 (または両方) のオペランドが 64 ビット整数の場合は、結果は 64 ビット整数になります。
整数の算術演算 (単項負符号を含む) の結果は、結果タイプの範囲内に なければなりません。
整数と 10 進数のオペランドを指定した算術演算
一方のオペランドが整数で、もう一方のオペランドが 10 進数の場合、演算は 10 進数で行われます。 算術演算では、10 進数に変換された整数の一時コピーが使用されます。
10 進数に変換された整数の一時コピーは、精度 p、位取り 0 です。p は、64 ビット整数の場合は 19、長精度整数の場合は 11、短精度整数の場合は 5 です。 整数定数の場合、p は整数定数の桁数によって決まります。 5 桁以下の整数定数の場合、p は 5 です。 それ以外の場合、p は整数定数の桁数と同じです。
整数と 10 進浮動小数点オペランドを使用した算術演算
一方のオペランドが短精度整数、長精度整数、または 64 ビット整数で、もう一方が 10 進浮動小数点数の場合、演算は 10 進浮動小数点で行われます。 算術演算では、10 進浮動小数点数に変換された整数の一時コピーが使用されます。
短精度整数または長精度整数の場合、整数は一時的に DECFLOAT(16) に変換されます。 64 ビット整数の場合、64 ビット整数は一時的に DECFLOAT(34) に変換されます。 その後で、2 つの 10 進浮動小数点オペランドに対する規則が適用されます。
2 つの 10 進数オペランドを指定した算術計算
オペランドが両方とも 10 進数の場合、その演算は 10 進数で行われます。
- オペランドの精度と位取り
- 2 つの 10 進数オペランドによる演算の解説では、第 1 オペランドの精度と位取りを p と s で表し、第 2 オペランドの精度と位取りを p' と s' で表すことにします。 したがって、除算の場合、被除数は精度が p で、位取りが s、除数は精度が p' で、位取りが s' となります。
- 演算について DEC31 と DEC15 のどちらが有効か
- DEC31 および DEC15 は、10 進演算で両方のオペランドの 精度が 15 以下の場合に使われる規則を指定します。 DEC15 は 15 桁を超える精度を認めない規則を指定し、DEC31 は 31 桁 までの精度を認める規則を指定します。 いずれかのオペランドの精度が 15 桁を超える場合には、DEC31 の規則が常に使用されます。
静的 SQL ステートメントの場合、インストール・パネル DSNTIP4 上のフィールド DECIMAL ARITHMETIC の値、または SQL 処理オプション DEC が、DEC15 と DEC31 の どちらを使用するかを決定します。
動的 SQL ステートメントの場合、以下の規則に従って DEC15 と DEC31 の どちらを使用するかは、インストール・パネル DSNTIP4 上の フィールド DECIMAL ARITHMETIC の値、SQL 処理オプション DEC、 または特殊レジスター CURRENT PRECISION により決められます。
- 以下のいずれかの条件が真の場合、フィールド DECIMAL
ARITHMETIC が適用されます。
- DYNAMICRULES の実行動作が適用され、アプリケーションが CURRENT
PRECISION を設定していない。
実行、バインド、定義、または呼び出しの動作を指定するDYNAMICRULESオプション値の一覧は、表1 を参照してください。
- DYNAMICRULES のバインド動作、定義動作、または呼び出し動作が適用され、 インストール・パネルのフィールド USE FOR DYNAMICRULES の値が YES であり、 アプリケーションが CURRENT PRECISION を設定していない。
- DYNAMICRULES の実行動作が適用され、アプリケーションが CURRENT
PRECISION を設定していない。
- SQL 処理オプション DEC が適用されるのは 、DYNAMICRULES のバインド動作、定義動作、または呼び出し動作が有効であり、 インストール・パネルのフィールド USE FOR DYNAMICRULES の値が NO であり、 アプリケーションが CURRENT PRECISION を設定していない場合です。
- アプリケーションがレジスターを設定する場合には、 特殊レジスター CURRENT PRECISION が適用されます。
DECIMAL ARITHMETIC の値は、SQL 処理オプションおよび 特殊レジスターのデフォルト値です。 SPUFI を使用して実行された SQL ステートメントは、DECIMAL ARITHMETIC の値を 使用します。
10 進数の加算と減算
10 進演算では、結果の精度と位取りは、オペランドの精度と位取りによって決まります。
加算演算または減算演算の場合に、両オペランドの位取りが 異なるときは、一方のオペランドのその小数部分の桁数がもう一方 のオペランドと同じになるように後続ゼロでそれを拡張した 一時コピーを使って、演算が行われます。
結果の精度は、n と数量 MAX(p-s,p'-s')+MAX(s,s')+1のうちの最小値です。 スケールは MAX(s,s')です。 DEC31 が有効な場合、あるいは少なくとも 1 つのオペランドの
精度が 15 を超える場合、n は 31 です。 そうでなければ、n は 15 です。
COBOL の場合は、COBOL ホスト変数名 (ダッシュの使用が許されている) とのあいまいさを避けるために、負符号の前後にブランクを入れる必要があります。
10 進数の乗算
10 進数の乗算では、結果の精度と位取りは、オペランドの精度と位取りによって決まります。
乗算の場合、結果の精度は MIN(n,p+p')であり、位取りは MIN(n,s+s')です。 DEC31 が有効な場合、あるいは少なくとも 1 つのオペランドの
精度が 15 を超える場合、n は 31 です。 そうでなければ、n は 15 です。
両方のオペランドの精度が 15 を超える場合は、精度が小さい
方のオペランドを一時的にコピーして演算が行われます。 両オペランドの精度が同じ場合には、第 2 オペランドが選択されます。 コピーの整数部分に 15 を超える有効数字が必要な場合、ステートメントの実行は終了し、エラーが発生します。 そうでなければ、コピーはその右端から切り捨てられて、精度 15 の数値に変換されます。 切り捨てられたコピーの位取りは、MAX(0,S-(P-15)) です。P と S は、元の精度と位取りです。 切り捨て処理において、1 つ以上の非ゼロ数字が除去された
場合には、精度が失われたことを示すために、SQLCA 内
の SQLWARN7 が W に設定されます。
両方のオペランドの精度が 15 を超える場合も、結果の精度と
位取りを表している前述の式が、1 つだけ変更がある他は同様に
適用されます。その変更とは、コピーするように選択されたオペランド
については、切り捨てられたコピーの精度と位取り、すなわち、精度
として 15、位取りとして MAX(0,S-(P-15)) を使うということです。
10000000000000000000000000. * 1オーバーフローが発生します。なぜなら、大きな数の31桁の表現における先頭ゼロの数と、小さな数の精度がいずれも5だからです。 整数と小数の演算子による算術演算を参照してください。整数と 10 進数のオペランドを指定した算術演算
一方のオペランドが整数で、もう一方のオペランドが 10 進数の場合、演算は 10 進数で行われます。 算術演算では、10 進数に変換された整数の一時コピーが使用されます。
10 進数に変換された整数の一時コピーは、精度 p、位取り 0 です。p は、64 ビット整数の場合は 19、長精度整数の場合は 11、短精度整数の場合は 5 です。 整数定数の場合、p は整数定数の桁数によって決まります。 5 桁以下の整数定数の場合、p は 5 です。 それ以外の場合、p は整数定数の桁数と同じです。
10 進数の除算
特定の小数点以下の桁数に関する規則は、 DEC31 オプションが演算に有効であるか、pが15より大きいか、p'が15より大きいかによって異なります。
次の表は、結果の精度と位取りが、これらの要因に応じて
どのように決まるのかを示しています。 その表では、行内に N/A
が出現するということは、示された要素がその行によって表されるケースに関連していないことを意味します。
| DEC31 | p | p' | P | S |
|---|---|---|---|---|
| 有効ではない | ≦15 | ≦15 | 15 | 15-(p-s+s') |
| 有効 | ≦15 | ≦15 | 31 | N-(p-s+s')、ここで
|
| 該当なし | 15 | ≦15 | 31 | N-(p-s+s')、ここで
|
| 該当なし | 該当なし | 15 | 31 | 15-(p-s+x)x は (次の注を参照) MAX(0,s'-(p'-15)) |
p' が 15 を超える場合、除算は除数の一時コピーを使って行われます。 除数の整数部分に 15 桁を超える有効数字が必要な場合には、
ステートメントの実行は終了し、エラーが発生します。 そうでなければ、コピーはその右端から切り捨てられて、精度 15 の数値に変換されます。 切り捨てられたコピーのスケールはMAX(0,s'-(p'-15))です。これは、x の式です。 切り捨て処理において、1 つ以上の非ゼロ数字が除去された
場合には、精度が失われたことを示すために、SQLCA 内
の SQLWARN7 が W に設定されます。
- 最小除算結果位取り
- 計算された「s」の値が負の場合には、エラーが発生します。 最小除算結果位取りが指定されている場合は、このエラーは発生しません。
最小除算結果位取りは、以下の優先順位に従って決定されます。
- 静的 SQL
- プリコンパイラー DEC オプション (ゼロ以外の位取りで設定されている場合)
- DECARTH サブシステム・パラメータ (ゼロ以外のスケールで設定されている場合)。
- MINDVSCL サブシステム・パラメータ (NONE 以外の値に設定されている場合)。
- DECDIV3 サブシステム・パラメータ (YES に設定されている場合)。
- 動的 SQL
- CURRENT PRECISION 特殊レジスター (ゼロ以外の位取りで設定されている場合)
- 以下のいずれかの場合:
- DYNAMICRULES RUN でバインドされたパッケージの場合、または DYNRULS DECP 値が YES に設定されている場合: DECARTH サブシステム・パラメータ (ゼロ以外のスケールで設定されている場合)。
- その他すべての場合は、プリコンパイラー DEC オプション (ゼロ以外の位取りで設定されている場合)
- MINDVSCL サブシステム・パラメータ (NONE 以外の値に設定されている場合)。
- DECDIV3 サブシステム・パラメータ (YES に設定されている場合)。
- SPUFI を使用して実行される SQL ステートメント
- DECARTH サブシステム・パラメータ値。
プリコンパイラー DEC オプションと CURRENT PRECISION 特殊レジスターのデフォルト値は、両方とも DECIMAL ARITHMETIC です。
最小除算結果位取り 3 は、DECDIV3 サブシステム・パラメータ設定を使用して指定できます。 1 ~ 9 の範囲の最小除算スケールの結果は、DECARTH サブシステム パラメーター値を使用して、「D pp. s 」という形式で指定できます。ここで、「 pp 」は 15 または 31 で精度を表し、「 s 」は 1 ~ 9 の範囲の数値として最小除算スケールを表します。 このような指定は、DECDIV3 サブシステム・パラメータをオーバーライドします。 最小除算結果位取りを指定すると、公式
MAX(s,s')が適用され (s は上記の表から導き出された位取りを表し、s' は最小除算結果位取りで指定された値を表す)、新しい位取りが導き出されます。 新しく導き出された位取りは結果の位取りを表し、上記の表を使って導き出され た位取りより優先します。
詳しくは、以下を参照してください。
浮動小数点オペランドを指定した算術計算
算術演算子のどちらかのオペランドが浮動小数点数の場合、 演算は浮動小数点数で行われます。 オペランドは、必要であれば、まずはじめに倍精度浮動小数点数に変換されます。 したがって、式のエレメントのいずれかが浮動小数点数の場合、 その式の結果は倍精度浮動小数点数になります。
浮動小数点数と整数が関係する演算は、整数を一時的に 倍精度浮動小数点数に変換したそのコピーを使って行われます。 浮動小数点数と 10 進数が関係する演算は、10 進数を一時的に 倍精度浮動小数点数に変換したそのコピーを使って行われます。 浮動小数点数演算の結果は、浮動小数点数の範囲内でなければなりません。
浮動小数点オペランドは実数の近似表現なので、浮動小数点オペランド (または関数の引数) が処理される順序が、 結果にわずかに影響する可能性があります。 オペランドが処理される順序は、 Db2 によって暗黙的に変更される可能性があるため(例えば、 Db2 が使用する並列処理の度合いやアクセス計画を決定する場合など)、浮動小数点オペランドを使用するアプリケーションは、SQLステートメントが実行されるたびに結果が正確に同じであることに依存すべきではありません。
浮動小数点と 10 進浮動小数点オペランドを指定した算術演算
一方のオペランドが浮動小数点数 (REAL または DOUBLE) で、もう一方が 10 進浮動小数点数の場合、演算は 10 進浮動小数点で行われます。 算術演算では、10 進浮動小数点数に変換された浮動小数点数の一時コピーが使用されます。
2 つの 10 進浮動小数点オペランドを指定した算術計算
両方のオペランドが 10 進浮動小数点の場合、演算は 10 進浮動小数点で行われます。 一方のオペランドが DECFLOAT(n) で、もう一方が DECFLOAT(m) の場合、演算は DECFLOAT(max(n,m)) で行われます。
DECFLOAT の一般的な算術演算規則
DECFLOAT データ・タイプに関する算術演算には、以下の一般規則が適用されます。
- 有限数に関する演算は、可能な場合は係数に対して整数算術計算を使用して、厳密な数学的結果を計算する場合と同様に行われます。
理論上正確な結果の係数が、精度を反映する桁数 (16 または 34) 以下である場合は、変更なく、それが結果に使用されます (アンダーフローまたはオーバーフロー条件が起きない限り)。 係数の桁数が精度を反映する桁数を上回る場合には、その精度を反映するちょうどの桁数 (16 または 34) に丸められて、取り除かれた桁数分だけ指数が増やされます。
CREATE VIEW 以外の静的 SQL ステートメントの場合、ROUNDING バインド・オプションまたはネイティブ SQL プロシージャーのオプションが丸めモードを決定します。
動的 SQL ステートメント (および静的 CREATE VIEW ステートメント) の場合、特殊レジスター CURRENT DECFLOAT ROUNDING MODE が丸めモードを決定します。
結果の調整された指数の値が Emin より小さい場合、例外条件が戻されます。 このケースでは、計算された係数と指数が、結果を形成します。ただし、指数の値が Etiny より小さい場合はその限りではありません。その場合 (小さい場合) には、指数は Etiny に設定され、指数の調整に一致するように係数が丸められ (場合によってはゼロに)、符号は変更されません。 この丸めによって不正確な結果になる場合は、アンダーフロー例外条件が戻されます。
調整された結果の指数の値が Emax よりも大きい場合は、オーバーフロー例外条件が戻されます。 このケースでは、結果はオーバーフロー例外条件として定義され、無限大になる可能性があります。 これは、理論的結果と同じ符号を持ちます。
- 特殊値の無限大を使用する算術計算は、通常の規則に従います。ここで、負の無限大はすべての有限数よりも小さく、正の無限大はすべての有限数よりも大きくなります。
こうした規則のもとでは、無限大の結果は常に正確です。 無限大のある種の使用は、無効な演算条件を戻します。 以下のリストは、無効演算条件が生じる可能性がある演算を示しています。オペランドの 1 つが無限大であるが、他方のオペランドが NaN でも sNaN でもない場合、演算の結果は NaN です。
- 加算または減算演算中に +infinity を -infinity に加算する
- 0 に +infinity または -infinity を乗算する
- +infinity または -infinity のいずれかを +infinity または -infinity のいずれかで除算する
- MOD 関数の最初の引数は、+infinity または -infinity のいずれかです。
- QUANTIZE 関数のいずれかの引数が +infinity または -infinity である
- POWER®関数の第2引数は、+∞または-∞です
- NaN (算術演算のオペランドとして使用される場合)
以下の算術計算規則は、算術演算および NaN 値に適用されます。
- オペランドが NaN (静止 NaN またはシグナリング NaN) であるすべての算術演算の結果は NaN です。 結果の符号は、信号 NaN である第 1 オペランドからコピーされます。どちらのオペランドも信号でない場合、符号は NaN である第 1 オペランドからコピーされます。 結果が NaN であるときはいつでも、結果の符号はコピーされたオペランドだけによって決まります。
- 乗算または除算の結果の符号が負になるのは、オペランドが異なる符号を持っており、どちらも NaN でない場合に限られます。
- 加算または減算の結果の符号が負になるのは、結果がゼロより小さく、どちらのオペランドも NaN でない場合に限られます。ただし、以下のケースは例外で、この場合、結果は負の 0 になります。
- 結果がゼロに丸められ、丸める前の値が負の符号を持っていた場合
- 0 から -0 を減算した場合
- 反対の符号を持つオペランドの加算 (または、同じ符号を持つオペランドの減算) で、結果の係数が 0、丸めモードが ROUND_FLOOR の場合
- 乗算または除算において、結果の係数が 0 で、オペランドの符号が異なる場合
- POWER 関数の第 1 引数が -0 で、第 2 引数が正の奇数である
- CEIL、FLOOR、または SQRT 関数の引数が -0 である
- ROUND または TRUNCATE 関数の第 1 引数が -0 である
INFINITY + 1 = INFINITY
INFINITY + INFINITY = INFINITY
INFINITY + -INFINITY = NAN -- exception
NAN + 1 = NAN
NAN + INFINITY = NAN
1 - INFINITY = -INFINITY
INFINITY - INFINITY = NAN -- exception
-INFINITY - -INFINITY = NAN -- exception
-0.0 - 0.0E1 = -0.0
-1.0 * 0.0E1 = -0.0
1.0E1 / 0 = INFINITY
-1.0E5 / 0.0 = -INFINITY
1.0E5 / -0 = -INFINITY
INFINITY / -INFINITY = NAN -- exception
INFINITY / 0 = INFINITY
-INFINITY / 0 = -INFINITY
-INFINITY / -0 = INFINITY特殊タイプ・オペランドを指定した算術計算
特殊タイプのソース・データ・タイプが数値であっても、 特殊タイプを算術演算子と組み合わせて使用することはできません。 算術演算を実行するには、 そのソースとしての算術演算子を使用する関数を作成する必要があります。 例えば、特殊タイプ INCOME と EXPENSES があり、両方のデータ・タイプが DECIMAL(8,2) の場合、次のユーザー定義関数 REVENUE を使用して、相互の減算を行うことができます。
CREATE FUNCTION REVENUE ( INCOME, EXPENSES )
RETURNS DECIMAL(8,2) SOURCE "-" ( DECIMAL, DECIMAL)
代わりに、関数を使用して - (マイナス) 演算子を多重定義することにより、 新しいデータ・タイプの減算を行うこともできます。
CREATE FUNCTION "-" ( INCOME, EXPENSES )
RETURNS DECIMAL(8,2) SOURCE "-" ( DECIMAL, DECIMAL)
また、特殊タイプを組み込みデータ・タイプにキャストして、 結果を算術演算子のオペランドとして使用することもできます。