1

数値フィールドとして小数点以下1000桁までの数値を含むフィールドを含むテキストファイルをインポートしています。次に、クエリを実行して更新し、SSN(ゼロの前)を修正して、数値フィールドから500を減算します。

UPDATE CODImportFile 
SET CODImportFile.[Original SSN] = Format([Original SSN],"000000000")
,   CODImportFile.[Lifetime Eligibility Used] = [Lifetime Eligibility Used]-500;

理由はわかりませんが、結果の一部は次のようになります。

Original:500.016
Result: 1.60000000000196E-02 

これを引き起こしている可能性のあるアイデアはありますか?

4

3 に答える 3

2

のデータ型[Lifetime Eligibility Used]はdoubleであるため、クエリでの計算は次のようになります。

SELECT
    CDbl(500.016) - 500 AS difference,
    TypeName(CDbl(500.016)-500) AS data_type;

...これを返します:

difference           data_type
1.60000000000196E-02 Double

これらの予期しない小数点以下の桁数は、バイナリシステムの小数点以下の計算に固有の不正確さの結果です。フィールドタイプをシングルに変換する(または計算でダブルをシングルにキャストする)こともできますが、それでも「余分な」小数点以下の桁数が得られます...これらの小数点以下の桁数は異なる値のセットです。

保存したくない小数点以下の桁数は破棄する必要があると思います。

UPDATE CODImportFile
SET [Lifetime Eligibility Used] =
    Round([Lifetime Eligibility Used]-500, 3);

次に、必要な丸め方法を決定するだけです。

? Round(0.1245, 3)
 0.124 

? CDbl(Format(0.1245, "0.000"))
 0.125
于 2012-10-11T16:42:10.027 に答える
0

これはおそらく、10 進数の結果を期待しているときに、SQL が数値を 2 進数として扱うことが原因です。一部の小数は、丸め誤差なしでは 2 進数として表すことができません。たとえば、.1 は正確に表すことができません。

10 進数を 2 進数で正確に表現できないのはなぜですか? を参照してください 。より多くの情報を得るために。

于 2012-10-11T15:07:45.470 に答える
0

結果は、元の数値から 500 を引いた後の "正しい" 余り (~0.016) です。とにかく浮動小数点数は正確ではありません...00196。そのため、最後に があります。精度に加えて、小数フィールドに適切なスケール (この場合はおそらく 3) を指定することで、これを修正できるはずです。

http://msdn.microsoft.com/en-us/library/aa258832(v=sql.80).aspxから:

decimal[(p[, s])] と numeric[(p[, s])]

精度と位取りの固定数値。最大精度が使用される場合、有効な値は - 10^38 +1 から 10^38 - 1 です。10 進数の SQL-92 シノニムは dec および dec(p, s) です。

p (精度)

小数点の左右両方に格納できる 10 進数の最大合計桁数を指定します。精度は、1 から最大精度までの値でなければなりません。最大精度は 38 です。デフォルトの精度は 18 です。

s (スケール)

小数点の右側に格納できる 10 進数の最大桁数を指定します。Scale は 0 から p までの値でなければなりません。位取りは、精度が指定されている場合にのみ指定できます。デフォルトのスケールは 0 です。したがって、0 <= s <= p です。最大ストレージ サイズは、精度によって異なります。

于 2012-10-11T15:21:25.060 に答える