MySQL целочисленные арифметические проблемы без знака?

StackOverflow https://stackoverflow.com/questions/1733460

  •  20-09-2019
  •  | 
  •  

Вопрос

Нравится ли MySQL (5.0.45) выполнять странные внутренние типизации с неподписанной математикой?Я храню целые числа без знака, но при выборе базовой арифметики я получаю возмутительные числа:

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)

Я предполагаю, что это связано с тем фактом, что вычитание отрицательное, и, таким образом, оно пытается сопоставить результаты с беззнаковым и переполненным?Очевидно, я могу решить эту проблему, изменив все на signed , но я бы предпочел иметь немного больше положительного пробела с моими 32-разрядными целыми числами.

Я не сталкивался с этим раньше в MySQL, и я почти уверен, что много работал с беззнаковой арифметикой MySQL;является ли это распространенной проблемой?

Это было полезно?

Решение

Если либо левая, либо правая часть оператора вычитания беззнаковая, то результат также беззнаковый.Вы можете изменить это, установив в NO_UNSIGNED_SUBTRACTION Режим SQL.

В качестве альтернативы, вы также можете явно преобразовать ваши значения без знака в подписанные значения bigint, а затем выполнить вычитание.

Другие советы

попробуй это:

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)

ссылка: http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html

Да, промежуточное вычитание привело к 64-битному завершению.Поскольку вы ожидали 32-битные целые числа, но на самом деле получили 64, нет причин использовать unsigned .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top