18

Oracle のドキュメントに矛盾する参照があります。10 進数を FLOAT に格納する方法とデータベースの NUMBER 型に格納する方法に違いはありますか?

C などから思い出したように、float には int にはない精度の制限があります。Rg、float の場合、0.1(Base 10) は 0.110011001100110011001101(Base 2) として概算されます。これは、およそ 0.100000001490116119384765625 (Base 10) のようなものです。ただし、int の場合、5(底 10) は正確に 101 (底 2) です。

これが、C で次のコードが期待どおりに終了しない理由です。

float i;
i = 0;
for (i=0; i != 10; )
{
    i += 0.1
}

ただし、Oracle のドキュメントの他の場所で、FLOAT が NUMBER として定義されていることがわかります。私が理解しているように、Oracle の NUMBER 型の実装では、C の float と同じ問題は発生しません。

それで、ここで本当の話は何ですか?Oracle は、float/FLOAT で起こると予想される標準から逸脱していますか?

(私がそれらを使用する目的については、ハリケーンの中の蜂の屁の違いであると確信していますが、0.1 * 10が1.00000000000000001になると疑問が生じることはわかっています)

4

5 に答える 5

29

OracleBINARY_FLOATは、C や他の多くの言語と同様に、IEEE 754 浮動小数点表現を使用してデータを内部的に格納します。それらをデータベースから取得し、通常はホスト言語の IEEE 754 データ型に格納すると、値を変換せずにコピーできます。

一方、 Oracle のFLOATデータ型は ANSI SQL NUMERIC データ型の同義語であり、Oracle では NUMBER と呼ばれます。これは正確な数値であり、IEEE 754 の丸め動作を持たないスケーリングされた 10 進数のデータ型です。ただし、これらの値をデータベースから取得して C または Java の float に入れると、このステップで精度が失われる可能性があります。

于 2008-12-01T22:53:23.167 に答える
10

Oracle BINARY_FLOATおよびBINARY_DOUBLEは、IEEE 754標準とほぼ同等ですが、標準のIEEE754表現に内部的に格納されていないことは間違いありません。

たとえば、BINARY_DOUBLEはIEEEの8に対して9バイトのストレージを使用します。また、倍精度浮動小数点数-3.0は3F-F7-FF-FF-FF-FF-FF-FFとして表され、実際のIEEEを使用する場合はC0-になります。 08-00-00-00-00-00-00。Oracle表現ではビット63が0であり、IEEE表現では1であることに注意してください(「s」が符号ビットの場合、IEEEによれば、数値の符号は(-1)^ sです)。http://babbage.cs.qc.cuny.edu/IEEE-754/で非常に優れたIEEE754計算機を参照してください。

クエリを使用してテーブルTにBINARY__DOUBLE列BDがある場合、これを簡単に見つけることができます。

TからBD、DUMP(BD)を選択します

これですべてがうまくて興味深いですが(多分)、Cで作業し、Oracleから数値を取得すると(変数を任意の種類の数値列にバインドすることにより)、通常、実際のIEEEdoubleで結果を取得します。 Cでサポートされています。現在、この値は通常のIEEEの不正確さの影響を受けます。

正確な算術演算を実行したい場合は、PL / SQLで実行するか、特別な正確な算術演算Cライブラリを使用して実行できます。

オラクル独自の数値データ型の説明については、http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/datatype.htm#i16209を参照してください。

于 2009-04-30T16:14:29.217 に答える
3

Oracle の Number は、実際には 10 進数 (基数 10) の浮動小数点表現です... Float は Number の単なるエイリアスであり、まったく同じことを行います。

Binary (base-2) float が必要な場合は、Oracle の BINARY_FLOAT または BINARY_DOUBLE データ型を使用する必要があります。

リンクテキスト

于 2008-12-01T22:46:00.233 に答える
2

前述の PLS_INTEGER と同様に、Oracle 10g の BINARY_FLOAT および BINARY_DOUBLE 型は機械演算を使用し、必要なストレージ スペースが少ないため、どちらも NUMBER 型よりも効率的です。

  • BINARY_FLOAT および BINARY_DOUBLE のみが NAN 値をサポートします

-正確な計算ではない

于 2015-08-07T06:01:51.463 に答える
2

Oracle の FLOAT に関する Bill の回答は、Oracle 8i では最新バージョン (たとえば 11i) に対してのみ正しいものであり、ドキュメントには次のように記載されています。

「NUMBERデータ型」で説明した形式で浮動小数点数を指定できます。Oracle は、ANSI データ型 FLOAT もサポートしています。次の構文形式のいずれかを使用して、このデータ型を指定できます。

FLOAT は、10 進精度 38 または 2 進精度 126 の浮動小数点数を指定します。FLOAT(b) は、2 進精度 b の浮動小数点数を指定します。精度 b の範囲は 1 ~ 126 です。2 進精度から 10 進精度に変換するには、b に 0.30103 を掛けます。10 進数から 2 進数の精度に変換するには、10 進数の精度に 3.32193 を掛けます。2 進精度の最大 126 桁は、10 進精度の 38 桁にほぼ相当します。

4 倍精度 (126 バイナリ精度) のように聞こえます。私が間違っていなければ、IEEE754 は単精度の場合は b = 2、p = 24、倍精度の場合は p = 53 のみを必要とします。8i と 11i の違いは、Oracle と PostgreSQL 間の変換計画を調べていたときに多くの混乱を引き起こしました。

于 2012-05-11T14:25:32.777 に答える