【问题标题】:MySQL integer unsigned arithmetic problems?MySQL整数无符号算术问题?
【发布时间】:2010-12-16 13:10:54
【问题描述】:

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)

我认为这与减法为负有关,因此它试图将结果映射为无符号和溢出?显然,我可以通过将所有内容更改为有符号来解决这个问题,但我更希望我的 32 位整数有更多的正空间。

我以前在 MySQL 上没有遇到过这种情况,我很确定我已经用无符号 MySQL 算法做了很多;这是一个常见的问题吗?

【问题讨论】:

标签: mysql integer math unsigned


【解决方案1】:

如果减法运算符的左侧或右侧是无符号的,则结果也是无符号的。您可以通过设置the NO_UNSIGNED_SUBTRACTION SQL mode 来更改此设置。

或者,您也可以将无符号值显式转换为有符号 bigint 值,然后进行减法。

【讨论】:

【解决方案2】:

是的,中间减法执行了 64 位环绕。由于您期望 32 位整数,但实际上得到 64,因此没有理由使用无符号数。

【讨论】:

  • 是的,想象一下我的内存图,显然我们能够维持每秒约 119,000 亿 yobibytes 的内存分配。这就是星际迷航计算。
【解决方案3】:

试试这个:

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

【讨论】:

    猜你喜欢
    • 2015-06-16
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    相关资源
    最近更新 更多