oracle 数据精度转换,【整理+原创】Oracle的计算精度与误差

原帖由 newkid 于 10-9-8 00:48 发表 thread-1345964-1-1.html

0.1肯定无法分解,可是oracle不会那么像你想的那样表示,它只用了两个字节表示。咱们按最土的办法,存一个小数点和一个1不也就可以了吗。

你的例子太复杂了,弄个简单的抵消的例子?我觉得很困难,误差只能积累。

两个字节,一个字节是8位,两个字节就是16位,对不?

我那样表示应该没错的,还没超过16位呢

3e5eac3ed29b33c2cd26d6970c929482.gif 要不然,oracle是怎么表示的呢?

5b24fae4cde99750994428c024162093.gif

不过我顺道做了测试,发现从0.1~0.9,dump出来的结果很有意思:

SCOTT@lw.lw> select dump(rownum/10) from dual connect by rownum<10;

DUMP(ROWNUM/10)

--------------------------------------------------------------------------------

Typ=2 Len=2: 192,11

Typ=2 Len=2: 192,21

Typ=2 Len=2: 192,31

Typ=2 Len=2: 192,41

Typ=2 Len=2: 192,51

Typ=2 Len=2: 192,61

Typ=2 Len=2: 192,71

Typ=2 Len=2: 192,81

Typ=2 Len=2: 192,91

已选择9行。

如果除以100或1000,还能有进一步的发现,在此就不赘述了,至少我自己还没找出什么特别有价值的东西。

但貌似这些比较符合你说的“可是oracle不会那么像你想的那样表示”

————————————————————————————————————————————————————

我的例子里没有抵消的,或者说有抵消的但我没看出来

5f60efcaccfa40b26873a6a9cb266119.gif

我尝试去找一下:

1、找出先除后乘后,存在计算误差的数

SCOTT@lw.lw> select rn, n, n1 from (select rownum rn, n, n/rownum*rownum

n1 from (select 1.39*10.5 n from dual) connect by rownum<40) where n1-n<>0;

RN          N         N1

---------- ---------- ----------

9     14.595     14.595

11     14.595     14.595

13     14.595     14.595

已用时间:  00: 00: 00.03

(在这里,先乘后除,试验了40万以内的正整数,没一个出现误差的)

2、构造序列,做笛卡尔积,找出误差被抵消的情况

SCOTT@lw.lw> with cand as ( select rn, n, n1 from (select rownum rn, n, n/

rownum*rownum n1 from (select 1.39*10.5 n from dual) connect by rownum<40) where

n1-n<>0),

2  t as (select rownum mp from dual connect by rownum<100)

3  select mp, rn, n, n1, n-n1, n-n1*mp/mp, n-n1/mp*mp from cand, t where n-n1*

mp/mp=0 or  n-n1/mp*mp=0

4  /

MP         RN          N         N1       N-N1 N-N1*MP/MP N-N1/MP*MP

---------- ---------- ---------- ---------- ---------- ---------- ----------

7          9     14.595     14.595 -3.000E-38          0          0

8          9     14.595     14.595 -3.000E-38          0          0

9          9     14.595     14.595 -3.000E-38          0 -3.000E-38

10          9     14.595     14.595 -3.000E-38          0          0

11          9     14.595     14.595 -3.000E-38          0 2.0000E-38

12          9     14.595     14.595 -3.000E-38          0          0

13          9     14.595     14.595 -3.000E-38          0 -3.000E-38

14          9     14.595     14.595 -3.000E-38          0          0

15          9     14.595     14.595 -3.000E-38          0 -3.000E-38

16          9     14.595     14.595 -3.000E-38          0 -3.000E-38

4         11     14.595     14.595 2.0000E-38 2.0000E-38          0

5         11     14.595     14.595 2.0000E-38 2.0000E-38          0

6         11     14.595     14.595 2.0000E-38 2.0000E-38          0

7         11     14.595     14.595 2.0000E-38          0          0

8         11     14.595     14.595 2.0000E-38          0          0

9         11     14.595     14.595 2.0000E-38          0 6.0000E-38

10         11     14.595     14.595 2.0000E-38          0          0

11         11     14.595     14.595 2.0000E-38          0 2.0000E-38

12         11     14.595     14.595 2.0000E-38          0          0

13         11     14.595     14.595 2.0000E-38          0 -3.000E-38

14         11     14.595     14.595 2.0000E-38          0          0

15         11     14.595     14.595 2.0000E-38          0 2.0000E-38

16         11     14.595     14.595 2.0000E-38          0 2.0000E-38

17         11     14.595     14.595 2.0000E-38          0 2.0000E-38

18         11     14.595     14.595 2.0000E-38          0 2.0000E-38

19         11     14.595     14.595 2.0000E-38          0 2.0000E-38

20         11     14.595     14.595 2.0000E-38          0 2.0000E-38

21         11     14.595     14.595 2.0000E-38          0 2.0000E-38

22         11     14.595     14.595 2.0000E-38          0 2.0000E-38

23         11     14.595     14.595 2.0000E-38          0 2.0000E-38

24         11     14.595     14.595 2.0000E-38          0 2.0000E-38

25         11     14.595     14.595 2.0000E-38          0 2.0000E-38

7         13     14.595     14.595 -3.000E-38          0          0

8         13     14.595     14.595 -3.000E-38          0          0

9         13     14.595     14.595 -3.000E-38          0 -3.000E-38

10         13     14.595     14.595 -3.000E-38          0          0

11         13     14.595     14.595 -3.000E-38          0 2.0000E-38

12         13     14.595     14.595 -3.000E-38          0          0

13         13     14.595     14.595 -3.000E-38          0 -3.000E-38

14         13     14.595     14.595 -3.000E-38          0          0

15         13     14.595     14.595 -3.000E-38          0 -3.000E-38

16         13     14.595     14.595 -3.000E-38          0 -3.000E-38

已选择42行。

3、验证一下:

选择上面标红的数据做验证,注意在下面的例子中,因为用到round函数,而小数点后第三位为5,所以一定要选取N-N1大于0的数据来做方能看出效果

SCOTT@lw.lw>select round(n,2) x, round(n/11*11,2) y, round(n/11*11/4*4,2)

z from (select 1.39*10.5 n from dual);

X          Y          Z

---------- ---------- ----------

14.6      14.59       14.6

误差抵消了????做个减法测试下:

SCOTT@lw.lw>select n-14.595 xx, n/11*11-14.595 yy,

n/11*11/4*4-14.595 zz from (select 1.39*10.5 n from dual);

XX         YY         ZZ

---------- ---------- ----------

0 -2.000E-38          0

果然如此,误差抵消了…………

5f60efcaccfa40b26873a6a9cb266119.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值