当我寻找下面的情况时,我没有找到答案。我有一个简单的值被四舍五入为0小数。我在oracle中尝试下面的查询,并获得如下所示:
select 1 / 3 * 19608 CORRECT from dual;
--6536 is correct
select TRUNC(1 / 3 * 19608, 0) WRONG from dual;
--6535 which is wrong
select TRUNC(1 / 3 * 19608, 2) WRONG from dual;
--6535.99 which is wrong请让我知道你是否有与这种情况有关的问题。
更新
很抱歉拒绝了你的回答。我发现还有一个问题你的回答仍然无效:
select TRUNC(1 / 3 * 15, 0) WRONG from dual;
--5 is correct小数字我得到的数字是正确的。这也是我所期望的,因为19608会导致错误的数值。19608是幻数吗?
更新2
我理解在下面的答案中所解释的数学。但我仍然对甲骨文TRUNC的功能表示怀疑,因为它没有像预期的那样提供正确的输出。现在,我想举例说明这一点,如下所示:
SELECT ( (4500 + ROWNUM) * 3) multiple_3,
TRUNC (1 / 3 * ( (4500 + ROWNUM) * 3), 2) result_with_trunc,
1 / 3 * ( (4500 + ROWNUM) * 3) no_trunc
FROM DUAL CONNECT BY 4500 + ROWNUM < 6000在上面的SQL中,您可以检查结果;准确地说,在500行之后,甲骨文的行为与可被3整除的数字不同。如果下面的答案是正确的,则意味着15000完全可以被3整除,而15003是而不是完全可以被3整除。
我希望这是有意义的,这与任何数学无关。
更新3
一个简单而直接的问题如下:
SQL> set numwidth 50
SQL> SELECT TRUNC(1 / 3 * 15000, 50) FROM dual;
TRUNC(1/3*15000,50)
--------------------------------------------------
5000
SQL> SELECT TRUNC(1 / 3 * 15003, 50) FROM dual;
TRUNC(1/3*15003,50)
--------------------------------------------------
5000.999999999999999999999999999999999999为什么我的oracle客户端(11.2.0.1.0)和服务器(11g 11.2.0.4.0 -64位)对一个可以被3整除的数字给出了不同的结果?
上一次更新-接受应答
@Lalit Kumar B谢谢你强调重复的十进制数。我遇到的情况不是先知的错。警报器正在正常工作。问题是0.3333.分数乘以一个可以被3整除的数,但不是完全的。这样的数字很少有300,15003,等等,
因此,当将ORACLE函数应用于1/ 3 *X乘法所产生的小数时,其结果是正确的,其中X不能完全被3整除。
发布于 2015-07-03 11:38:27
查询和输出都没有问题。您的客户端是第一个查询输出中值的舍入。
SQL> SELECT TRUNC(1 / 3 * 19608, 50) FROM dual;
TRUNC(1/3*19608,50)
-------------------
6536
SQL> set numwidth 50
SQL> SELECT TRUNC(1 / 3 * 19608, 50) FROM dual;
TRUNC(1/3*19608,50)
--------------------------------------------------
6535.999999999999999999999999999999999999
SQL>在我的SQL*Plus客户机中,我调整了数字宽度,您可以看到实际值。
此外,在甲骨文中,scale对于数字数据类型有限制,可以达到100%的准确性。这个限制是38位数字,你不能100%的准确地发布。您需要理解尾数、和指数。在这种情况下,scale对指数的可能最小值设置了一个限制。
更新 OP更新了这个问题。
选择TRUNC(1 /3* 15,0)从对偶错误;-5是正确的
与甲骨文无关。它是纯mathematics.15完全可以被3整除,因此得到一个整数 5。
19608是幻数吗?
19608不是完全可除的被3,您将有小数部分。我已经展示了上面的内容。(1/3)*19608的正确结果是而不是 6536。正确的结果是6535.9和循环的十进制。它永远不会被3整除。
更新2 OP更新了这个问题。
SQL> set numwidth 50
SQL> SELECT (1/3)*5000*3 FROM dual;
(1/3)*5000*3
--------------------------------------------------
5000.000000000000000000000000000000000001
SQL> SELECT (1/3)*(5000*3) FROM dual;
(1/3)*(5000*3)
--------------------------------------------------
5000
SQL> SELECT trunc((1/3)*(5000*3),2) FROM dual;
TRUNC((1/3)*(5000*3),2)
--------------------------------------------------
5000
SQL> SELECT 1 / 3 * 15003 FROM dual;
1/3*15003
--------------------------------------------------
5000.999999999999999999999999999999999999
SQL> SELECT 15003/3 FROM dual;
15003/3
--------------------------------------------------
5001上述对类似(,而非相同的)操作的查询结果不同的原因是,Oracle从左到右计算。
当您执行1/3*n时,Oracle的计算结果与n/3不同。在前一种情况下,首先计算1/3,从而创建一个recurring non-terminating decimal number 0.3333....,其中3是递归数字。现在,当你用一个3的倍数乘以它时,它已经失去了的精度,因此最终的结果也将是循环的非终止数。
当您将其放入大括号中时,您要求Oracle显式地计算大括号内的部分,而不仅仅是从左到右。因此,下面两个是在中不以相同方式计算的:
1 / 3 * 15003的计算方法与
15003/3https://stackoverflow.com/questions/31205778
复制相似问题