免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2943 | 回复: 6
打印 上一主题 下一主题

不知是否是BUG,ABS()在mysql 不能取得正确值。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-26 12:36 |只看该作者 |倒序浏览
不知是否是BUG,ABS()在mysql 不能取得正确值。

环境:
服务器版本: 5.1.31-community



有一个表,两个tinyint(3)类型的非零字段(A,B)。

使用下列语句:
select abs(a-b) from table;
select abs(a)-abs(b) from table;

当B大于A时,均不能得到正确的值。

论坛徽章:
0
2 [报告]
发表于 2009-04-26 13:02 |只看该作者
刚刚更新到5.1.34


问题一样。

论坛徽章:
0
3 [报告]
发表于 2009-04-26 19:26 |只看该作者
能不能把你的表里的部分数据和结构贴一下呢?

论坛徽章:
0
4 [报告]
发表于 2009-04-27 11:47 |只看该作者
应该不会有这么低级的错误,,,楼主把数据和结果帖一下。

论坛徽章:
0
5 [报告]
发表于 2009-04-27 12:58 |只看该作者
CREATE TABLE IF NOT EXISTS `abc` (
  `id` int(11) NOT NULL,
  `id1` tinyint(3) unsigned DEFAULT NULL,
  `id2` tinyint(3) unsigned DEFAULT NULL,
  `id3` tinyint(3) unsigned DEFAULT NULL,
  `id4` tinyint(3) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=1;

select * from abc

返回值:

        id         id1         id2         id3         id4
        1         1         2         3         4        
        2         1         2         3         5        
        3         1         2         3         6        
        4         1         2         3         7        
        5         1         2         3         8        



SELECT id1 - id2, id2 - id3, id3 - id4
FROM   abc;
返回值:

            id1-id2                                         id2-id3                                        id3-id4
18446744073709551615         18446744073709551615         18446744073709551615
18446744073709551615         18446744073709551615         18446744073709551615
18446744073709551615         18446744073709551615         18446744073709551615
18446744073709551615         18446744073709551615         18446744073709551615
18446744073709551615         18446744073709551615         18446744073709551615





select abs(id1-id2) from abc;
返回值:
abs(id1-id2)
18446744073709551615
18446744073709551615
18446744073709551615
18446744073709551615
18446744073709551615





select 1-5,6-7,9-3;

返回值:

1-5         6-7         9-3
-4         -1         6





以上是部分表结构,部分数据,以及一些测试。

论坛徽章:
0
6 [报告]
发表于 2009-04-27 14:04 |只看该作者
18446744073709551615
这个值是bigint unsigned 的最大值。

MySQL内部的运算是按地址运算的。

二进制减法运算的原理:减去一个正数相当于加上一个负数A-B=A+(-B),对(-B)求补码,然后进行加法运算。
1-2
过程: 0000 00001 - 0000 0010 = 0000 0001 +(-0000 0010)
#在这个求补码的过程中,按整数最大值来求了。用8个字节表示了。
          =0000 00001 + (11111111  1111 1111  1111 1111 1111 1111  1111 1111 1111 1111 1111 1111 1111 1101 + 1 )
          =11111111  11111111  11111111 11111111  11111111 11111111 11111111 11111111

mysql> select hex(18446744073709551615);
+---------------------------+
| hex(18446744073709551615) |
+---------------------------+
| FFFFFFFFFFFFFFFF          |
+---------------------------+
1 row in set (0.00 sec)

参考:
http://zhidao.baidu.com/question/36780022.html
http://www.mysqlsupport.cn/2009/04/mysql-4int-unsigned.html

评分

参与人数 1可用积分 +5 收起 理由
枫影谁用了 + 5 精品文章

查看全部评分

论坛徽章:
0
7 [报告]
发表于 2009-04-27 21:10 |只看该作者
LS的回答不错。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP