2014-01-10 47 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 

最终浮点数的任何十进制表示具有限制其精度,并且将近似。两个函数给出略微不同的近似值可能有点令人困惑,但由于它们似乎更接近于近似值(尽管文档中提到了这一点) - 作为一种特殊情况 - 我不确定这是否真的有什么值得抱怨的地方。