2014-01-10 52 views
2

最近我發現ORACLE函數POWER並不總是給出確切的結果。 這可以通過該腳本或類似容易地檢查:Oracle函數POWER給出近似結果

BEGIN 
FOR X IN 1 .. 100 LOOP 
    IF SQRT(X) = POWER(X, 1/2) THEN 
    DBMS_OUTPUT.PUT_LINE(X); 
    END IF; 
END LOOP; 
END; 

的輸出功率結果只是如下:1,5,7,11,16,24,35,37,46,48,53,70, 72,73. 也就是說我們從僅有100個第一自然數的14個案例中看到情況,其中數字的平方根等於其索引爲1/2的指數。

+0

問題是什麼?這只是觀察。 – San

+0

現在無法訪問sqlplus。嘗試用'X ** 0.5'替換'POWER(X,1/2)'。 – ibre5041

+0

您正試圖比較實數。你需要截斷到你想要的精度。 – Glenn

回答

2

我認爲這與NUMBER數據類型的限制有關。我相信NUMBER精度只能達到38個最大值。如果您有BINARY_DOUBLE嘗試,你會發現所有的值1-> 100將匹配:

DECLARE 
    l_num binary_double := 0; 
BEGIN 
    LOOP 
     l_num := l_num + 1; 
     exit when l_num > 100; 
     IF (SQRT(l_num) = POWER(l_num, 0.5)) THEN 
      DBMS_OUTPUT.PUT_LINE(l_num); 
     ELSE 
      DBMS_OUTPUT.PUT_LINE(l_num || ': ' || SQRT(l_num) || ' <> ' || POWER(l_num, 0.5)); 
     END IF; 
    END LOOP; 
END; 

輸出(部分):

1.0E+000 
2.0E+000 
3.0E+000 
... 
9.8E+001 
9.9E+001 
1.0E+002 

另一種選擇是既圓SQRT和權力的結果例如35或更小(如果您必須使用NUMBER數據類型)。

2

Oracle documentation somewhat covers this

數值函數

數字函數接受數字輸入和返回的數值。大多數 數字函數返回的NUMBER值精確到38位十進制 數字。的超越函數COSCOSHEXPLNLOGSINSINHSQRTTAN,和TANH精確到36張 十進制數。超越函數ACOS,ASIN,ATAN, 和ATAN2精確到30位十進制數。

所以SQRT據說是精確到36位十進制數;但POWER不在列表中,因此暗示它精確到38個十進制數字。如果您查看兩個函數返回的值,則可以看到差異最小的數字;例如爲X = 2

SQRT(2):  1.41421356237309504880168872420969807857 
POWER(2, 1/2): 1.41421356237309504880168872420969807855 

然而奇怪的是,它看起來像SQRT更準確,這是POWER是稍微不太精確,如你所說。Wolfram Alpha gives

   1.4142135623730950488016887242096980785696718753769480... 

(但是請注意,還稱這是一個近似值),這輪以相同的SQRT;如果你有SQRT(2) * SQRT(2)逆轉這一過程,並POWER((POWER(2, 1/2), 2)你:

(SQRT):  2 
(POWER):  1.99999999999999999999999999999999999994 

Xbinary_double而非number你會得到兩個相同的值:

   1.4142135623730951 

,但你已經失去了精度;再次平方給出:

   2.0000000000000004 

最終浮點數的任何十進制表示具有限制其精度,並且將近似。兩個函數給出略微不同的近似值可能有點令人困惑,但由於它們似乎更接近於近似值(儘管文檔中提到了這一點) - 作爲一種特殊情況 - 我不確定這是否真的有什麼值得抱怨的地方。