2009-11-14 18 views
5

¿Le gusta a MySQL (5.0.45) hacer tipos de letra internos extraños con matemática sin signo? Estoy almacenando enteros sin signo, pero la hora de seleccionar la aritmética básica consigo cifras escandalosas:MySQL entero sin signo problemas aritméticos?

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) 

Asumo que esto tiene que ver con el hecho de que la resta es negativo y por lo tanto se trata de un mapa de los resultados en un sin firmar y desbordante ? Puedo resolver esto aparentemente cambiando todo para firmar, pero preferiría tener un poco más de espacio positivo con mis enteros de 32 bits.

No me he encontrado con esto antes en MySQL y estoy bastante seguro de que he hecho muchas cosas con la aritmética MySQL sin firmar; ¿Es este un problema común?

+0

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

Respuesta

7

Si el lado izquierdo o el lado derecho del operador de resta no está firmado, el resultado tampoco está firmado. Puede cambiar esto configurando the NO_UNSIGNED_SUBTRACTION SQL mode.

Alternativamente, también puede emitir explícitamente sus valores sin firmar para que sean valores bigint firmados y luego hacer la resta.

+0

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

2

Sí, la resta intermedia hizo un envolvente de 64 bits. Como esperaba números enteros de 32 bits, pero en realidad obtiene 64, no hay razón para usar unsigned.

+0

Sí, imagino mis gráficos de memoria cuando aparentemente pudimos mantener la asignación de memoria en ~ 119 mil billones de yobibytes por segundo. Esa es la computación Star Trek allí mismo. – Xailor

3

intente esto:

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) 

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

Cuestiones relacionadas