2014-01-05 62 views
4

使用SQL Server 2008 R2,當我輸入以下查詢:SQL服務器電源功能

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

其產生的結果:

9223372036854775800 

然而,使用Windows桌面計算器,提高2到63收益率:

9223372036854775807 

有人可以解釋差異 - 或者是否有一些內部轉換ñSQL Server正在做什麼? ...還是我想念別的東西?

+0

但它被轉換成BIGINT - 夥計們 - 打開你的Windows桌面計算器並輸入2提高到63 - 它給出了9223372036854775807 - 它與SQL文檔中的上限相匹配9,223,372,036,854,775,807 - so你如何使用SQL POWER函數來得到相同的答案? – bdcoder

回答

6

BIGINT在MS SQL Server的範圍是:

-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

+0

首先,2^63不能是'9223372036854775807',如果你檢查'9223372036854775807 = 2^63-1'。然而,在這裏他正在計算'2^63',它大於BIGINT可以容納的。 – manman

+0

夥計們 - 打開你的Windows桌面計算器,並輸入2提高到63 - 它給出了9223372036854775807 - 它匹配SQL文檔的9,223,372,036,854,775,807的上限 - 所以你如何使用SQL POWER函數來得到相同的回答????? – bdcoder

+0

你不能。浮點運算不能保證準確。 –

2

電力將被返回浮動。浮點數不準確超過一定的限制,並會降低一些準確性(如果你曾經有一個負0問題,你會明白我的意思!)。

這就是你在這裏得到什麼?

+0

我沒有真正檢查它給出的答案是錯誤的,但確實檢查了有效數字的數量> 14.我的經驗是,DOUBLE在14或更多時間開始失去精度。 –

+0

高達+/- 328,是的! (不知道它實際上是328,但它接近!) –

+0

然而,給定的否定,限制實際上是2^63-1 - 並不那麼容易! –

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,因爲你已經把權力的第一個參數投給了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的限制。

請注意,減法周圍的()是真正需要的。否則,首先完成兩個權力的結果的添加,再次導致溢出。