Oracle函数POWER提供近似结果

时间:2014-01-10 16:10:22

标签: oracle

最近我发现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。 即我们看到的情况是,只有14个案例来自100个第一个自然数,一个数的平方根等于它的指数为1/2的指数。

2 个答案:

答案 0 :(得分: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和POWER的结果舍入到35或更小(如果必须使用NUMBER数据类型)。

答案 1 :(得分:2)

Oracle documentation somewhat covers this

  

数字函数

     

数字函数接受数字输入并返回数值。最   数字函数返回精确到38十进制的NUMBER值   数字。先验函数COSCOSHEXPLN,   LOGSINSINHSQRTTANTANH的准确值为36   十进制数字。先验函数ACOSASINATAN,   并且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

最终浮点数的任何十进制表示都有其精度的限制,并且将是近似值。给出略微不同的近似值的两个函数可能有点令人困惑,但是因为它们似乎有SQRT更近似(尽管文档中说的是) - 作为一个特例 - 我不确定这是否真的值得抱怨