Pregunta

¿Tiene MySQL (5.0.45) gusta hacer typecasts internos extraños con las matemáticas sin firmar? Estoy almacenando enteros sin signo, pero la hora de seleccionar la aritmética básica consigo cifras escandalosas:

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 está tratando de mapear los resultados en un sin firmar y desbordante? Puedo resolver esto, al parecer, cambiando todo para firmado, pero yo prefiero tener un poco de espacio más positiva con mis enteros de 32 bits.

No se han topado con esto antes de MySQL y estoy bastante seguro de que he hecho un montón con la aritmética de MySQL sin firmar; esto es un problema común?

¿Fue útil?

Solución

Si bien el lado izquierdo o el lado derecho del operador de resta es sin signo, el resultado no está firmado también. Puede cambiar esto estableciendo el modo NO_UNSIGNED_SUBTRACTION SQL .

Como alternativa, también se puede convertir explícitamente sus valores sin signo para ser firmados valores BIGINT y luego hacer la resta.

Otros consejos

intente lo siguiente:

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)

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

Sí, la resta intermedio hizo una envolvente de 64 bits. Dado que esperaba enteros de 32 bits, pero en realidad obtener 64, no hay razón para usar sin firmar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top