输入以下查询时使用SQL Server 2008 R2:
SELECT CAST(POWER(2.0, 63.0) AS BIGINT);
产生结果:
9223372036854775800
但是,使用Windows桌面计算器并将2提高到63会产生:
9223372036854775807
有人可以解释一下这个区别 - 或者SQL Server正在进行一些内部转换? ...或者我错过了其他什么?
答案 0 :(得分:6)
MS Sql Server中BIGINT
的范围是:
-2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807)
你的计算器给你错误的数字,因为2 ^ 63的最右边的数字不能有一个奇数。
SQL Server中的POWER
函数(http://technet.microsoft.com/en-us/library/ms174276.aspx)返回与第一个参数相同的类型。
编写此查询的正确方法是:
DECLARE @foo REAL = 2.0
SELECT CAST(POWER( @foo, 63.0 ) AS BIGINT)
通过它,您将收到Arithmetic overflow error converting expression to data type bigint.
错误消息。
关于这个原因
http://www.extremeoptimization.com/resources/Articles/FPDotNetConceptsAndFormats.aspx
关于为什么POWER
函数返回错误数字的问题?正如@simonatrcl在他的回答中提到的,浮点数存在算术问题,有时会导致无效结果。您可以在这里阅读浮点数及其问题:
http://www.extremeoptimization.com/resources/Articles/FPDotNetConceptsAndFormats.aspx
您还可以在此处检查MS Sql Server中整数类型的边界: http://technet.microsoft.com/en-us/library/ms187745.aspx
答案 1 :(得分:2)
电力将返回FLOAT。浮点数不准确超出一定限度,并且会降低一些准确度(如果你有一个负0问题,你就会明白我的意思!)。
这就是你在这里得到的......
答案 2 :(得分:0)
计算器在XP,Win7和Win8.1上进行测试: 2 ^ 63 = 9223372036854775808(显然)
就MSSQL而言: BIGINT的上限定义为2 ^ 63-1,意味着1小于2 ^ 63 现在,如果您希望MSSQL为您计算,那么您可能会想要编写类似的内容:
SELECT POWER(CAST(2 AS BIGINT), 63) - 1
结果将是一个很大的因为你已经将权力的第一个论点转化为bigint。 MSSQL将首先计算功率然后减去1.然而,由于功率的结果将超出bigint的范围,因此该语句将失败:Arithmetic overflow error converting expression to data type bigint.
因此,让我们调用一些数学来解决这个问题。我假设每个人都同意
2^4 = 2 * 2 * 2 * 2 = 2 * (2^3) = 2^3 + 2^3
因此
2^4-1 = 2 * 2 * 2 * 2 - 1 = 2 * (2^3) - 1 = 2^3 + 2^3 - 1
这就是我们要利用的......
SELECT POWER(CAST(2 AS BIGINT), 62) + (POWER(CAST(2 AS BIGINT), 62) - 1)
这导致9223372036854775807
确实是bigint的上限。
请注意,确实需要减法周围的()。否则,将首先添加两个幂的结果,再次导致溢出。