2009-11-14 6 views
5

Tut MySQL (5.0.45) gerne seltsame interne Typumwandlungen mit unsignierten Mathe? Ich bin zu speichern ganze Zahlen unsigned aber als Grundrechen Auswahl ich empörend Zahlen:MySQL ganze Zahl vorzeichenlose arithmetische Probleme?

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) 

Ich nehme an, dies mit der Tatsache zu tun hat, dass die Subtraktion negativ ist und somit versucht, die Ergebnisse in ein unsigned abzubilden und überfüllt ? Ich kann das scheinbar lösen, indem ich alles auf unterschrieben ändere, aber ich hätte lieber etwas mehr Platz mit meinen 32-Bit-Ganzzahlen.

Ich habe nicht schon vorher auf MySQL und ich bin mir ziemlich sicher, dass ich viel mit unsigned MySQL Arithmetik getan habe; Ist das ein häufiges Problem?

+0

Duplizieren: http://stackoverflow.com/questions/1517556/mysql-query-gone-wild –

Antwort

7

Wenn entweder die linke Seite oder die rechte Seite des Subtraktionsoperators unsigniert ist, ist das Ergebnis ebenfalls vorzeichenlos. Sie können dies ändern, indem Sie the NO_UNSIGNED_SUBTRACTION SQL mode einstellen.

Alternativ können Sie auch Ihre vorzeichenlosen Werte explizit in signierte Bigint-Werte umwandeln und dann die Subtraktion durchführen.

+0

New docs Link: http: // dev.mysql.com/doc/refman/5.7/de/sql-mode.html#sqlmode_no_unsigned_subtraction ............................. .................................................. ........................ MariaDB: https://mariadb.com/kb/en/mariadb/sql_mode/ –

2

Ja, die Zwischensubtraktion hat einen 64-Bit-Wraparound. Da Sie 32-Bit-Ganzzahlen erwarten, aber tatsächlich 64 erhalten, gibt es keinen Grund, unsigniert zu verwenden.

+0

Ja, stellen Sie sich meine Gedächtnis-Grafiken vor, wenn es scheint Wir waren in der Lage, die Speicherzuweisung bei ~ 119 Milliarden Milliarden Yobibyte zu halten zweite. Das ist Star Trek Computing genau dort. – Xailor

3

versuchen Sie dies:

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) 

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