MySQL interi senza segno problemi di aritmetica?
Domanda
La MySQL (5.0.45) piace fare strani typecasts interne con la matematica non firmati? Sto Memorizzazione di numeri interi senza segno, ma quando si seleziona l'aritmetica di base ottengo numeri ingiuriosi:
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)
Suppongo che questo ha a che fare con il fatto che la sottrazione è negativo e quindi si sta cercando di mappare i risultati in un unsigned e traboccante? Posso risolvere questo apparentemente cambiando tutto firmato, ma preferirei avere un po 'di spazio più positivo con i miei interi a 32 bit.
Non ho eseguito in questo prima su MySQL e sono abbastanza certo che ho fatto un sacco con unsigned aritmetica MySQL; questo è un problema comune?
Soluzione
Se sia sul lato sinistro o il lato destro l'operatore di sottrazione non è firmato, il risultato non è firmato pure. È possibile modificare questo impostando la modalità NO_UNSIGNED_SUBTRACTION
SQL .
In alternativa, è anche possibile lanciare in modo esplicito i valori non firmato da firmare valori bigint e poi fare la sottrazione.
Altri suggerimenti
provare questo:
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)
di riferimento: http://dev.mysql.com /doc/refman/5.0/en/cast-functions.html
Sì, la sottrazione intermedio ha fatto un 64-bit avvolgente. Dal momento che vi aspettavate 32 bit interi, ma in realtà arrivare a 64, non c'è alcun motivo per utilizzare senza segno.