Pergunta

O MySQL (5.0.45) gosta de fazer espécies internas estranhas com matemática não assinada? Estou armazenando números inteiros não assinados, mas ao selecionar aritmética básica, recebo números ultrajantes:

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)

Suponho que isso tenha a ver com o fato de que a subtração é negativa e, portanto, está tentando mapear os resultados em um não assinado e transbordando? Eu posso resolver isso aparentemente mudando tudo para assinar, mas prefiro ter um espaço um pouco mais positivo com meus números inteiros de 32 bits.

Eu não encontrei isso antes no MySQL e tenho certeza de que fiz muito com aritmética MySQL não assinada; Isso é um problema comum?

Foi útil?

Solução

Se o lado esquerdo ou o lado direito do operador da subtração não for assinado, o resultado também não será assinado. Você pode mudar isso configurando a NO_UNSIGNED_SUBTRACTION Modo SQL.

Como alternativa, você também pode lançar explicitamente seus valores não assinados para serem assinados valores Bigint e depois fazer a subtração.

Outras dicas

Experimente isso:

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)

referência: http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html

Sim, a subtração intermediária fez um envoltório de 64 bits. Como você esperava que os números inteiros de 32 bits, mas na verdade obtenham 64, não há razão para usar não assinado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top