メインコンテンツまでスキップ
バージョン: 26.x

浮動小数点型(FLOATとDOUBLE)

説明

Dorisは2つの浮動小数点データ型を提供します:FLOATDOUBLE。これらは浮動小数点演算のIEEE 754標準に従う可変精度数値型です。

タイプAliasStorage Sizeデスクリプション
FLOATFLOAT4, REAL4 bytes単精度浮動小数点
DOUBLEFLOAT8, DOUBLE PRECISION8 bytes倍精度浮動小数点

値の範囲

FLOAT

DorisはIEEE-754単精度浮動小数点数を使用し、値の範囲は以下の通りです:

  • -∞ (-Infinity)
  • [-3.402E+38, -1.175E-37]
  • 0
  • [1.175E-37, 3.402E+38]
  • +∞ (+Infinity)
  • NaN (Not a Number)

詳細については、C++ float typeおよびWikipedia Single-precision floating-point formatを参照してください。

DOUBLE

DorisはIEEE-754倍精度浮動小数点数を使用し、値の範囲は以下の通りです:

  • -∞ (-Infinity)
  • [-1.79769E+308, -2.225E-307]
  • 0
  • [+2.225E-307, +1.79769E+308]
  • +∞ (+Infinity)
  • NaN (Not a Number)

詳細については、C++ double typeおよびWikipedia Double-precision floating-point formatを参照してください。

特殊値

通常の数値に加えて、浮動小数点型はIEEE 754標準に準拠したいくつかの特殊値を持ちます:

  • InfinityまたはInf:正の無限大
  • -Infinityまたは-Inf:負の無限大
  • NaN:Not a Number

これらの特殊値はCASTによる変換を通じて生成できます:

mysql> select cast('NaN' as double), cast('inf' as double), cast('-Infinity' as double);
+-----------------------+-----------------------+-----------------------------+
| cast('NaN' as double) | cast('inf' as double) | cast('-Infinity' as double) |
+-----------------------+-----------------------+-----------------------------+
| NaN | Infinity | -Infinity |
+-----------------------+-----------------------+-----------------------------+

浮動小数点数には直感的ではない性質もあります。2つの異なるゼロ値、+0-0が存在します。 ほとんどのコンテキストでは等しいとみなされますが、符号ビットが異なります。

mysql> select cast('+0.0' as double), cast('-0.0' as double);
+------------------------+------------------------+
| cast('+0.0' as double) | cast('-0.0' as double) |
+------------------------+------------------------+
| 0 | -0 |
+------------------------+------------------------+

Floating-Point演算

算術演算

Dorisの浮動小数点数は、加算、減算、乗算、除算などの一般的な算術演算をサポートしています。

Dorisは浮動小数点数の0による除算を処理する際に、IEEE 754標準に完全には従わないことに注意することが重要です。

この点において、DorisはPostgreSQLの実装に従い、0で除算した場合に特殊値を生成する代わりにSQL NULLを返します:

ExpressionPostgreSQLIEEE 754Doris
1.0 / 0.0ErrorInfinityNULL
0.0 / 0.0ErrorNaNNULL
-1.0 / 0.0Error-InfinityNULL
'Infinity' / 'Infinity'NaNNaNNaN
1.0 / 'Infinity'0.00.00
'Infinity' - 'Infinity'NaNNaNNaN
'Infinity' - 1.0InfinityInfinityInfinity

比較演算

IEEE標準は、重要な点で一般的な整数比較とは異なる浮動小数点比較を定義しています。例えば、負のゼロと正のゼロは等しいとみなされ、任意のNaN値は他のどの値とも等しくありません(それ自身を含む)。すべての有限浮動小数点数は+∞より厳密に小さく、-∞より厳密に大きいです。

結果の一貫性と予測可能性を確保するため、DorisはIEEE標準とは異なる方法でNaNを処理します。 DorisではNaNは他のすべての値よりも大きい(Infinityを含む)とみなされ、NaNはNaNと等しくなります。

mysql> select * from sort_float order by d;
+------+-----------+
| id | d |
+------+-----------+
| 5 | -Infinity |
| 2 | -123 |
| 1 | 123 |
| 4 | Infinity |
| 8 | NaN |
| 9 | NaN |
+------+-----------+

mysql> select
cast('Nan' as double) = cast('Nan' as double) ,
cast('Nan' as double) > cast('Inf' as double) ,
cast('Nan' as double) > cast('123456.789' as double);
+-----------------------------------------------+-----------------------------------------------+------------------------------------------------------+
| cast('Nan' as double) = cast('Nan' as double) | cast('Nan' as double) > cast('Inf' as double) | cast('Nan' as double) > cast('123456.789' as double) |
+-----------------------------------------------+-----------------------------------------------+------------------------------------------------------+
| 1 | 1 | 1 |
+-----------------------------------------------+-----------------------------------------------+------------------------------------------------------+

Floating-Point精度の問題

近似値と精度の損失

浮動小数点数は本質的に近似表現です。これは、特定の十進値が浮動小数点数のバイナリ表現では正確に格納できず、代わりに近似値として格納されることを意味します。その結果、格納と取得の際に小さな誤差が発生する可能性があります。

例:

mysql> SELECT CAST(1.3 AS FLOAT) - CAST(0.7 AS FLOAT) = CAST(0.6 AS FLOAT);
+--------------------------------------------------------------+
| CAST(1.3 AS FLOAT) - CAST(0.7 AS FLOAT) = CAST(0.6 AS FLOAT) |
+--------------------------------------------------------------+
| 0 |
+--------------------------------------------------------------+

浮動小数点表現エラーのため、これは期待通りにTRUEと評価されない場合があります。

演算は結合法則に従わない

浮動小数点演算の精度制限により、浮動小数点数の計算特性は理論的な数学演算と異なります。浮動小数点の加算と乗算は結合法則と分配法則に厳密には従いません。

これにより重要な結果が生じます:異なる計算順序により、わずかに異なる結果が生成される可能性があります。 DorisはMPPアーキテクチャを使用しており、データ処理の正確な順序を保証できないため、浮動小数点数を含む計算では、同一の入力データであっても、異なる実行でわずかに異なる結果が生成される可能性があります。

集約関数

浮動小数点値に対して集約関数を実行すると、特に大規模なデータセットを扱う際にエラーが蓄積される可能性があります。データに極めて大きい値や小さい値が含まれている場合、これらのエラーはさらに増幅される可能性があります。 計算順序が不確定なため、データに極値が含まれている場合、同じ集約関数を複数回実行すると異なる結果が得られる場合があります。

Join操作

集約関数と同様に、浮動小数点列でのTablejoinの実行は推奨されません。浮動小数点数の精度問題により、理論的に等しい2つの値が内部表現でわずかに異なる可能性があり、マッチに失敗する原因となります。

浮動小数点出力

浮動小数点数が文字列に変換される際、Dorisは以下の精度ルールに従います:

  • 単精度浮動小数点数(FLOAT)は少なくとも7桁の有効数字を保証
  • 倍精度浮動小数点数(DOUBLE)は少なくとも16桁の有効数字を保証 浮動小数点出力は科学記法を使用する場合があるため、浮動小数点の文字列表現の長さは必ずしもその有効数字数と等しくないことに注意してください:
mysql> select cast('1234567' as float) , cast('12345678' as float);
+--------------------------+---------------------------+
| cast('1234567' as float) | cast('12345678' as float) |
+--------------------------+---------------------------+
| 1234567 | 1.234568e+07 |
+--------------------------+---------------------------+

ベストプラクティス

  1. 適切なデータ型を選択する: 金融計算やその他の正確な数値が必要なシナリオでは、浮動小数点型の代わりにDECIMAL型を使用してください。

  2. 等価比較に注意する: 特にJOIN操作において、2つの浮動小数点値が等しいかどうかを直接比較することは避けてください。

  3. 文字列変換に注意する: 浮動小数点数を文字列に変換してから戻すと、追加の精度損失が発生する可能性があります。

  4. プラットフォームの違いを理解する: 異なるデータベースシステムでは、浮動小数点演算の処理において微妙な違いがある場合があります。特にNaNやInfinityなどの特殊なケースを扱う際には注意が必要です(ただし、ほとんどのデータベースシステムは広くIEEE標準に従っています)。

  5. 表示用に結果を適切に丸める: 浮動小数点計算結果を表示する際は、ユーザーに対する精度の問題を軽減するため、適切な丸め処理を検討してください。

キーワード

FLOAT, FLOAT4, REAL, DOUBLE, DOUBLE PRECISION, FLOAT8, floating-point