2

私はすべてを見てきましたが、この答えを見つけることができません。

MySQL の実際の桁数は何桁FLOATですか?

FLOATの 4 バイト制限を超えるものを切り捨てることは知っていますが (と思いますか?)、それは正確には何ですか?

4

2 に答える 2

6

マニュアルから(強調鉱山):

FLOATの場合、SQL標準では、括弧内のキーワードFLOATに続くビットでの精度(指数の範囲ではない)のオプション指定が許可されています。MySQLはこのオプションの精度仕様もサポートしていますが、精度値はストレージサイズを決定するためにのみ使用されます。精度が0から23の場合、4バイトの単精度FLOAT列になります。精度が24から53の場合、8バイトの倍精度DOUBLE列になります。

したがって23、仮数の最大ビットの精度をFLOATに格納できます。これは、2 ^ 23〜10 ^ 7(8,388,608対10,000,000)であるため、小数点以下7桁に相当します。ここでテストしました。10進数の12桁が返され、そのうち最初の7桁だけが実際に正確であることがわかります。

于 2013-02-01T00:16:16.120 に答える
2

MySQL は float を Java などと同じように扱うと思っている人のために、ショッキングなニュースを入手しまし。これをチェックしてください:

ジャワ:

public static void main(String[] args) {
    long i = 16777225;
    DecimalFormat myFormatter = new DecimalFormat("##,###,###");
    float iAsFloat = Float.parseFloat("" + i);
    System.out.println("long i = " + i + " becomes " + myFormatter.format(iAsFloat));
}

出力は

long i = 16777225 becomes 16,777,224

これまでのところ、とても正常です。この例の整数は 2^24 = 16777216 のすぐ上です。2^23 と 2^24 の間の 23 ビットの仮数部により、浮動小数点数はすべての整数を保持できます。次に、2^24 から 2^25 までは偶数のみを保持でき、2^25 から 2^26 までは 4 で割り切れる数のみを保持できます。 0.5 のすべての倍数を保持できます)。指数が範囲外でない限り、それが float が格納できるルールです。

16777225 は奇数です。したがって、その範囲 (2^24 から 2^25 まで) では float の「ステップ サイズ」が 2 であるため、「float バージョン」は 1 つオフです。

そして今、MySQL はそれをどのように構成するのでしょうか。

あなたが私を信じない場合に備えて、ここにフィドルがあります(私は信じません)

http://www.sqlfiddle.com/#!2/a42e79/1

CREATE TABLE IF NOT EXISTS `test` (
     `test` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `test`(`test`) VALUES (16777225)

SELECT * FROM `test`

結果:

16777200

結果は 1 ではなく 25 ずれていますが、100 で割り切れるという「利点」があります。どうもありがとうございました。

このまったくナンセンスの背後にある「哲学」は理解できると思いますが、賛成とは言えません。以下がその「理由」です。

彼らは、「実際の」浮動小数点数 (JAVA と業界標準による) を 10 の適切な累乗に丸めることによって達成する、間違っている可能性のある小数点以下の桁数を表示したくありません。

この例では、そのままにしておくと、最後の桁が間違っていてゼロにならず、それができません。

次に、10 の倍数に丸めると、正しい値は 16777230 になり、「実際の」浮動小数点数は 16777220 に丸められます。7 桁目が間違っています (以前は間違っていませんでしたが、現在は間違っています。 ) そしてそれはゼロではありません。私たちはそれを持つことはできません。100 の倍数に丸めた方がよいでしょう。これで、正しい値と「実際の」浮動小数点値の両方が 16777200 に丸められます。したがって、正しい 6 桁のみが表示されます。末尾の "24" を知りたくありません。これは、元の数値が 1677723 から 1677725 の間である必要があることを (ステップ サイズがその範囲で 2 であるため) 伝えているためです。いいえ、知りたくありません。 ; これらの 2 つの数値は、7 桁に四捨五入したの 7 桁が異なるため、「適切な」7 桁がわからないため、6 桁で停止する必要があります。ともかく、

したがって、彼らの目標は、元の正確な数を四捨五入した場合 (前にfloat に変換) を 6 桁に変換します。また、log_base10(2^23) = 6.92 (切り捨ては 6) であるため、これが常に機能すると彼らが考えている理由がわかります。悲しいことに、それでさえ真実ではありません。

例:

私は = 33554450

数値は 2^25 から 2^26 の間であるため、その「float バージョン」(つまり、MySQL float バージョンではなく、JAVA float バージョン) は 4 の最も近い倍数です (正しい場合は小さい方)。中)、つまり

i_as_float = 33554448

小数点以下 6 桁 (つまり、8 桁の数字なので 100 の倍数) に四捨五入すると、33554500 が得られます。

i_as_float を 6 桁に丸めると、33554400 になります。

おっとっと!それらは6桁目で異なります!しかし、MySQL の人には言わないでください。16777200 を 16777000 に向けて「改善」し始めるかもしれません。

アップデート

他のデータベースはそのようにはしません。

フィドル: http://www.sqlfiddle.com/#!15/d9144/1

于 2014-09-26T08:11:01.393 に答える