神谷 雅紀
Escalation Engineer
real および float 浮動小数点データ型においてアンダーフローが発生した場合、エラーは発生しません。0 が設定されます。
各データ型で格納可能な数値範囲は以下の通りです。
データ型 | 格納可能な数値範囲 |
real | - 3.40E+38 ~ -1.18E-38、0、および 1.18E-38 ~ 3.40E+38 |
float | - 1.79E+308 ~ -2.23E-308、0、および 2.23E-308 ~ 1.79E+308 |
以下は、その動作を確認することのできる簡単なサンプルです。
float 型に格納可能な最小値よりも小さな 2.23E-309 を格納しようとすると、結果は 0 になります。それを示す警告も返されます。
declare @r float
set @f = 2.23E-309
select @f as 'float'警告: 浮動小数点値 '2.23E-309' は小さすぎます。この値は 0 と見なされます。
float
----------------------
0
real が格納可能な数値よりも小さな数値 1.18E-39 を格納しようとすると、結果は 0 になります。
declare @r real
set @r = 1.18E-39
select @r as 'real'real
-------------
0
1.18E-39 を格納可能な float に一旦入れた後に、それを real にコピーしても 0 になります。
declare @r real, @f float
set @f = 1.18E-39
set @r = @f
select @f as 'float', @r as 'real'
float real
---------------------- -------------
1.18E-39 0
計算の結果としてアンダーフローが発生した場合も 0 になります。
declare @r real
set @r = 1.18E-38
select @r as '1.18E-38'
set @r = @r * @r
select @r as '1.18E-38 * 1.18E-38'
1.18E-38
-------------
1.18E-38
1.18E-38 * 1.18E-38
-------------------
0
追加情報
SQL Server 2012 では浮動小数点型パラメータを使用した RPC (* 1) において、real 型の範囲を超えた値を渡すと以下のエラーが発生するという問題がありました。
エラーメッセージ
着信の表形式のデータ ストリーム (TDS) リモート プロシージャ コール (RPC) のプロトコル ストリームが正しくありません。パラメーター X ("XXX"): 指定した値はデータ型 real の有効なインスタンスではありません。ソース データに無効な値があるかどうかを確認してください。たとえば、小数点以下桁数が有効桁数より大きい数値型のデータは無効です。
この問題は、以前のバージョンでは許可されていなかった非正規化浮動小数点数 (denormalized float/real) が、現在のバージョンでは許可されているものの、一部不要なチェックが残っていたために発生していました。
この問題は SQL Server 2014 では修正されています。この修正により、浮動小数点型パラメーターの値として real 型の範囲を超えた値を渡していたアプリケーションでは、SQL Server 2012 ではエラーになっていたものが、SQL Server 2014 では値 0 として扱われるようになります。
(*1) RPC: Remote Procedure Call の略。クライアントアプリケーションが SQL Server に対して要求を送信する方法のひとつ。バッチ (Batch) もしくは Language と呼ばれる方法が SQL Server に対して T-SQL 文字列を渡すのに対して、RPC は呼び出すストアドプロシージャの名前もしくは番号と各パラメーターのデータ型および値を渡す。SQL トレースや拡張イベントのイベント名 “RPC:Completed” などの “RPC” はこれ。