【问题标题】:SQL Server POWER functionSQL Server POWER 函数
【发布时间】:2014-01-05 18:12:07
【问题描述】:

当我输入以下查询时使用 SQL Server 2008 R2:

SELECT CAST(POWER(2.0, 63.0) AS BIGINT);

产生结果:

9223372036854775800

但是,使用 Windows 桌面计算器并将 2 提高到 63 产生:

9223372036854775807

有人能解释一下区别吗——或者 SQL Server 是否正在做一些内部转换? ...还是我错过了什么?

【问题讨论】:

  • 但它被转换为 BIGINT -- 伙计们 -- 打开你的 windows 桌面计算器并输入 2 提高到 63 -- 它给出 9223372036854775807 -- 这与 SQL 文档中的上限相匹配9,223,372,036,854,775,807 -- 那么你如何使用 SQL POWER 函数来获得相同的答案?????

标签: sql sql-server sql-server-2008-r2 bigint


【解决方案1】:

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 (http://technet.microsoft.com/en-us/library/ms174276.aspx) 中的 POWER 函数返回与其第一个参数相同的类型。

这个查询的正确写法是:

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

【讨论】:

  • 首先,2^63 不能是9223372036854775807,如果你检查9223372036854775807 = 2^63 - 1。然而,他在这里试图计算2^63,它比 BIGINT 可以容纳的更大。
  • 伙计们 -- 打开你的 Windows 桌面计算器并输入 2 到 63 -- 它给出 9223372036854775807 -- 这与 SQL 文档中的上限 9,223,372,036,854,775,807 相匹配 -- 那么你如何使用SQL POWER 函数得到相同的答案??????
  • 你不能。浮点运算不保证准确。
  • @user1377587 对于如此大的数字,您不能相信 Windows 计算器的结果。 2 的任何数字的幂将有一个偶数,因为它的最右边的数字而不是奇数!这是一个简单的计算规则。如果您在这里尝试相同的计算online-calculator.com/scientific-calculator,您将看到0 作为结果
  • 如果你们尝试DECLARE @foo BIGINT = 2.0 SELECT POWER( @foo, 63 ),您将在 SQL Server 中收到Arithmetic overflow error converting expression to data type bigint. 错误。
【解决方案2】:

Power 将返回一个 FLOAT。浮点数超出某些限制是不准确的,并且会降低一点准确性(如果您曾经遇到过负 0 问题,您就会明白我的意思!)。

这就是你在这里得到的......

【讨论】:

  • 我实际上并没有检查它给出的答案是否错误,但确实检查了 > 14 的有效位数。我的经验是 DOUBLE 在 14 或更多时开始失去精度。
  • 最多大约 +/- 328,是的! (不确定它实际上是 328,但它很接近!)
  • 然而,考虑到负数,限制实际上是 2^63-1 - 没那么容易!
  • 前面的两个 cmets 是对一个自删除后的评论的回应,该评论类似于“但它应该能够轻松应对 2 的 int 幂”。该评论已被删除。
【解决方案3】:

就计算器而言,并在 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,因为您已将幂的第一个参数转换为一个 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 的上限。

请注意,确实需要减法周围的 ()。否则将首先完成两个幂的结果相加,再次导致溢出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 2021-04-17
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多