在程序或函数中执行时算术运算的结果不准确(oracle)

时间:2017-09-13 07:55:07

标签: plsql numbers decimal-point

我试图计算受雇员工资影响的项目,但算术运算的结果不准确,例如返回99.99999999999999而不是100。这只发生在过程或函数内部,但在分离的sql查询中正常工作。

EX:

CREATE TABLE SS_TEST_CUT
(
  CUT  NUMBER
);

create or replace procedure ss_test (x1 number , x2 number , num out number) 
as 
x number ; 
begin 
    x := 100; 
    num := (x/30) *(30 - x1 - x2); 
    insert into ss_test_cut (cut) values (trunc (num,2));
end;

select cut from  ss_test_cut;

实际结果是:99.99 预期结果:100

在程序外,该程序给出了预期的结果。

select (100/30 ) * 30 from dual; 输出:100

为什么以及如何避免这种情况,因为其他数字有分数? 谢谢,

2 个答案:

答案 0 :(得分:1)

编辑:好了,现在问题稍微清楚一点,程序正在产生99.9重复,这与100不一样,特别是当你向下舍入时。但是,我仍然没有看到PL / SQL在SQL正确的情况下给出了错误的结果。正如鲍勃的回答所示,100 / 30 * 30(100 * 30) / 30是两回事。

这是显示格式问题(编辑:除非你向下舍入......)

SQL> select 100 / 30 * 30 from dual;

 100/30*30
----------
       100

SQL> select to_char(100 / 30 * 30) from dual;

TO_CHAR(100/30*30)
----------------------------------------
99.9999999999999999999999999999999999999

99.9经常出现,100次实际上是相同的。

这是另一个示例,表明过程中的结果与直接使用SQL时的结果相同:

SQL> create table demo (label varchar2(10), result number);

Table created.

SQL> insert into demo values ('SQL', 100 / 30 * 30);

1 row created.

SQL> declare
  2      num number;
  3  begin
  4      num := 100 / 30 * 30;
  5
  6      insert into demo values ('PL/SQL', num);
  7  end;
  8  /

PL/SQL procedure successfully completed.

SQL> select label, result, to_char(result) from demo;

LABEL          RESULT TO_CHAR(RESULT)
---------- ---------- ----------------------------------------
SQL               100 99.9999999999999999999999999999999999999
PL/SQL            100 99.9999999999999999999999999999999999999

2 rows selected.

答案 1 :(得分:1)

重新排序计算中的操作以避免中间舍入:

val df_withalias = df.withColumn("myalias",
  when(df("c1") === 0 || isnull(df("c1")),
    when(isnull(df("c2")/df("c3")), 1).otherwise(df("c2")/df("c3"))
  ).otherwise(df("c1"))
)

假设x1和x2为零,按预期工作。

祝你好运。