关于MySQL的第一个查询出了什么问题?
两列的预期答案是' 718042670591505846'
SELECT 5002622390 + (5102 * 140737488355328) new_iid_hard_way,
CAST(5002622390 + (5102 * POWER(2,47)) AS UNSIGNED) new_iid_WRONG_way
它返回:
' 718042670591505846',' 718042670591505792'
同时,此查询有效:
SELECT 5002622390 + (5102 * 140737488355328) new_iid_hard_way,
5002622390 + (5102 * CAST(POWER(2,47) AS UNSIGNED)) new_iid_CORRECT_way
它返回: ' 718042670591505846',' 718042670591505846'
我的预感是它是一个数据类型溢出/包装问题......但即使在MySQL 5.6.15上启用严格模式,我也不会收到任何错误。
有趣的是,在所有4种情况下,sqlfiddle都错了:
http://sqlfiddle.com/#!9/d1bb6/1
返回718042670591505800
这是溢出问题吗?如果是,那么为什么在启用严格模式时MySQL不会抛出错误?
答案 0 :(得分:1)
有些操作在DECIMAL
完成,有些操作在DOUBLE
完成。这可以解释为什么数字在第16位有效数字之后会有所不同。
这是另一种方法:
5002622390 + (5102 << 47)
<<
是二元移位,因此它与*POW(2, ...)
使用DECIMAL得到718042670591505846的正确答案:
SELECT CAST(5002622390 AS DECIMAL) + (5102 * 140737488355328);
SELECT CAST(5002622390 AS DECIMAL) + (5102 << 47)