Home > Archive > Other Oracle database topics > October 2005 > Roundoff error question









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Roundoff error question
Don Del Grande

2005-10-27, 11:23 am

I am trying to figure out exactly how ORACLE (I am currently using 8i)
handles arithmetic with NUMBERs. I have some idea how numbers are
stored internally, but I can't figure out how a particular operation
gets a particular result.

Here's what I have:
(Autocommit is on)

CREATE TABLE roundoff_error (N NUMBER);
INSERT INTO roundoff_error(N) values(1/190);
UPDATE roundoff_error SET N = N * 10;
UPDATE roundoff_error SET N = N * 19;
UPDATE roundoff_error SET N = N - 1;
SELECT * FROM roundoff_error;

This returns -6 x 10^(-40).

However, I get something slightly different:
1/190 = 100^(-1) x 0. 52631578947368421052
631578947368421053 (rounded to
the 38th significant digit).
Multiplying by 10, an extra 0 needs to be added on the left to maintain
the proper exponent, so the last significant digit is lost:
100^0 x 0. 05263157894736842105
263157894736842105
Multiply this by 19:
100^0 x 0. 09999999999999999999
999999999999999995
Subtract 1; the result in -5 x 10^(-38).

Did I miss something painfully obvious?
Did I make a mistaken assumption somewhere - for example, am I right in
assuming NUMBERs are stored with an implied zero to the left of the
decimal point? (e.g. 1 is actually stored as 100^1 * 0.01?) Would
that affect the result?

-- Don

Mark D Powell

2005-10-27, 11:23 am

I have added a select after each update. The difference is where you
have .09.. in your calculations the query shows a value of 1.

UT1 > set numwidth 38
UT1 > CREATE TABLE roundoff_error (N NUMBER);

Table created.

UT1 > INSERT INTO roundoff_error(N) values(1/190);

1 row created.

UT1 > SELECT * FROM roundoff_error;

N
--------------------------------------
.. 00526315789473684210
52631578947368421

UT1 > UPDATE roundoff_error SET N = N * 10;

1 row updated.

UT1 > SELECT * FROM roundoff_error;

N
--------------------------------------
.. 05263157894736842105
26315789473684211

UT1 > UPDATE roundoff_error SET N = N * 19;

1 row updated.

UT1 > SELECT * FROM roundoff_error;

N
--------------------------------------
1

UT1 > UPDATE roundoff_error SET N = N - 1;

1 row updated.

UT1 > SELECT * FROM roundoff_error;

N
--------------------------------------
-6. 00000000000000000000
00000000000E-40

HTH -- Mark D Powell --

Don Del Grande

2005-10-27, 11:23 am

Mark D Powell wrote:
> I have added a select after each update. The difference is where you
> have .09.. in your calculations the query shows a value of 1.
>
> UT1 > CREATE TABLE roundoff_error (N NUMBER);
> UT1 > INSERT INTO roundoff_error(N) values(1/190);
> UT1 > UPDATE roundoff_error SET N = N * 10;
> UT1 > SELECT * FROM roundoff_error;
>
> N
> --------------------------------------
> . 05263157894736842105
26315789473684211


At this point, I get:
0. 05263157894736842105
26315789473684210526

(I used numwidth 50 to make sure I got all of the digits)

Now I see where ORACLE is getting -6 x 10^(-40).
However, I don't understand where the 39th significant digit is coming
from - I thought ORACLE only maintained 38 significant digits in
NUMBERs.

Can anybody tell me why there are 39 significant digits? Is this a
"hidden feature" of some sort of ORACLE where it will maintain a 39th
digit if the first digit in the first stored byte is zero (so it would
use 20 bytes in the mantissa - otherwise only 37 significant digits
would be maintained)?

-- Don

Sponsored Links





Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive | Programming forum archive

Copyright 2008 droptable.com