最近我发现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的指数。
答案 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值 数字。先验函数
COS
,COSH
,EXP
,LN
,LOG
,SIN
,SINH
,SQRT
,TAN
和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
当X
为binary_double
而不是number
时,您获得两者的相同值:
1.4142135623730951
但是你失去了精确度;再次平息,给出了:
2.0000000000000004
最终浮点数的任何十进制表示都有其精度的限制,并且将是近似值。给出略微不同的近似值的两个函数可能有点令人困惑,但是因为它们似乎有SQRT
更近似(尽管文档中说的是) - 作为一个特例 - 我不确定这是否真的值得抱怨