Oracleのドキュメント で競合する参照が表示されます。小数がFLOATに格納される方法とデータベースのNUMBERタイプに違いはありますか?
Cらから思い出したように、floatには、intにはない精度の制限があります。たとえば、「float」の場合、0.1(基数10)は0.110011001100110011001101(基数2)として概算されます。これは、おおよそ0.100000001490116119384765625(基数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と同じ問題は発生しません。
それで、ここでの本当の話は何ですか?オラクルは、フロート/フロートで発生すると予想される基準から逸脱しましたか?
(これは、私がそれらを使用する目的とは異なるハリケーンの蜂であると確信していますが、0.1 * 10が1.00000000000000001になるかどうか、質問があることはわかっています)
オラクルのBINARY_FLOAT
Cや他の多くの言語と同様に、IEEE754浮動小数点表現を使用してデータを内部的に格納します。それらをデータベースからフェッチし、通常はホスト言語のIEEE 754データ型で保存すると、値を変換せずにコピーできます。
一方、OracleのFLOAT
データ型は、OracleではNUMBERと呼ばれるANSI SQLNUMERICデータ型の同義語です。これは正確な数値であり、IEEE 754の丸め動作を持たないスケーリングされた10進数データ型です。ただし、これらの値をデータベースからフェッチしてCまたはJava float 、このステップで精度が失われる可能性があります。
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表現ではビット63が1であることに注意してください(IEEEによれば、「s」が符号ビットの場合、数値の符号は(-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
OracleのNumberは、実際には10進数(基数10)の浮動小数点表現です... FloatはNumberの単なるエイリアスであり、まったく同じことを行います。
バイナリ(基数2)フロートが必要な場合は、OracleのBINARY_FLOATまたはBINARY_DOUBLEデータ型を使用する必要があります。
前述のPLS_INTEGERと同様に、Oracle 10gのBINARY_FLOATタイプとBINARY_DOUBLEタイプは、マシン演算を使用し、必要なストレージスペースが少ないため、どちらもNUMBERタイプよりも効率的です。
-正確な計算ではありません
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を掛けます。最大126桁の2進精度は、38桁の10進精度にほぼ相当します。
四倍精度(126バイナリ精度)のように聞こえます。私が誤解しない限り、IEEE754は単精度の場合はb = 2、p = 24、倍精度の場合はp = 53のみを必要とします。 OracleとPostgreSQLの間の変換計画を検討していたとき、8iと11iの違いは多くの混乱を引き起こしました。