5

MySQL(5.0.45)は、符号なしの数学を使用して奇妙な内部型キャストを実行するのが好きですか?符号なしの整数を格納していますが、基本的な算術を選択すると、とんでもない数値が表示されます。

mysql> create table tt ( a integer unsigned , b integer unsigned , c float );
Query OK, 0 rows affected (0.41 sec)

mysql> insert into tt values (215731,216774,1.58085);
Query OK, 1 row affected (0.00 sec)

mysql> select a,b,c from tt;
+--------+--------+---------+
| a      | b      | c       |
+--------+--------+---------+
| 215731 | 216774 | 1.58085 |
+--------+--------+---------+
1 row in set (0.02 sec)

mysql> select (a-b)/c from tt;
+---------------------+
| (a-b)/c             |
+---------------------+
| 1.1668876878652e+19 |
+---------------------+
1 row in set (0.00 sec)

mysql> -- WHAT?
mysql> select a-b from tt;
+----------------------+
| a-b                  |
+----------------------+
| 18446744073709550573 |
+----------------------+
1 row in set (0.02 sec)

これは、減算が負であり、結果を符号なしでオーバーフローにマッピングしようとしているという事実に関係していると思いますか?すべてを符号付きに変更することでこれを解決できるようですが、32ビット整数でもう少し正のスペースを使用したいと思います。

私はこれまでMySQLでこれに遭遇したことがなく、符号なしのMySQL演算で多くのことを行ったことがあると確信しています。これは一般的な問題ですか?

4

3 に答える 3

7

減算演算子の左側または右側のいずれかが符号なしの場合、結果も符号なしになります。これは、NO_UNSIGNED_SUBTRACTIONSQLモードを設定することで変更できます。

または、符号なしの値を明示的にキャストして符号付きのbigint値にしてから、減算を実行することもできます。

于 2009-11-14T06:21:52.023 に答える
3

これを試して:

mysql> select cast(cast(a-b as unsigned) as signed)/c from tt;

+-----------------------------------------+
| cast(cast(a-b as unsigned) as signed)/c |
+-----------------------------------------+
|                       -659.771639688953 | 
+-----------------------------------------+
1 row in set (0.00 sec)

参照:http ://dev.mysql.com/doc/refman/5.0/en/cast-functions.html

于 2009-11-14T06:51:07.733 に答える
2

ええ、中間減算は 64 ビットのラップアラウンドを行いました。32 ビット整数を期待していましたが、実際には 64 になるため、符号なしを使用する理由はありません。

于 2009-11-14T06:21:58.557 に答える