代码之家  ›  专栏  ›  技术社区  ›  Jé Queue

mysql整数无符号算术问题?

  •  5
  • Jé Queue  · 技术社区  · 16 年前

    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算法做了很多工作;这是一个常见的问题吗?

    3 回复  |  直到 16 年前
        1
  •  7
  •   James McNellis    16 年前

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

    或者,也可以显式地将无符号值强制转换为有符号的bigint值,然后进行减法运算。

        2
  •  3
  •   user210925    16 年前

    试试这个:

    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

        3
  •  2
  •   wallyk    16 年前

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