Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

rekharaghuram
from rekharaghuram More from this publisher
05.11.2015 Views

CHAPTER 12 ■ DATATYPES 505 • BINARY_DOUBLE: This is an IEEE native double-precision floating-point number. On disk it will consume 9 bytes of storage: 8 fixed bytes for the floating-point number and 1 length byte. It is capable of storing numbers in the range of ~ ± 10 308.25 with 13 digits of precision. As you can see from this quick overview, the Oracle NUMBER type has significantly larger precision than the BINARY_FLOAT and the BINARY_DOUBLE types, but a much smaller range than the BINARY_DOUBLE. That is, you can store numbers very precisely with many significant digits in a NUMBER type, but you can store much smaller and larger numbers in the BINARY_FLOAT and BINARY_DOUBLE types. As a quick example, we can create a table with the various datatypes in them and see what is stored given the same inputs: ops$tkyte@ORA10GR1> create table t 2 ( num_col number, 3 float_col binary_float, 4 dbl_col binary_double 5 ) 6 / Table created. ops$tkyte@ORA10GR1> insert into t ( num_col, float_col, dbl_col ) 2 values ( 1234567890.0987654321, 3 1234567890.0987654321, 4 1234567890.0987654321 ); 1 row created. ops$tkyte@ORA10GR1> set numformat 99999999999.99999999999 ops$tkyte@ORA10GR1> select * from t; NUM_COL FLOAT_COL DBL_COL ------------------------ ------------------------ ------------------------ 1234567890.09876543210 1234567940.00000000000 1234567890.09876540000 Note that the NUM_COL returns the exact number we provided as input. There are fewer than 38 significant digits in the input number (I supplied a number with 20 significant digits), so the exact number is preserved. The FLOAT_COL, however, using the new BINARY_FLOAT type, was not able to accurately represent this number. In fact, it preserved only 7 digits accurately. The DBL_COL faired much better, accurately representing the number in this case out to 17 digits. Overall, though, this should be a good indication that the BINARY_FLOAT and BINARY_DOUBLE types will not be appropriate for financial applications! If you play around with different values, you’ll see different results: ops$tkyte@ORA10GR1> delete from t; 1 row deleted. ops$tkyte@ORA10GR1> insert into t ( num_col, float_col, dbl_col ) 2 values ( 9999999999.9999999999, 3 9999999999.9999999999,

506 CHAPTER 12 ■ DATATYPES 4 9999999999.9999999999 ); 1 row created. ops$tkyte@ORA10GR1> select * from t; NUM_COL FLOAT_COL DBL_COL ------------------------ ------------------------ ------------------------ 9999999999.99999999990 10000000000.00000000000 10000000000.00000000000 Once again, the NUM_COL accurately represented the number, but the FLOAT_COL and DBL_COL cannot. This does not mean that the NUMBER type is able to store things with “infinite” accuracy/precision—just that it has a much larger precision associated with it. It is easy to observe similar results from the NUMBER type: ops$tkyte@ORA10GR1> delete from t; 1 row deleted. ops$tkyte@ORA10GR1> insert into t ( num_col ) 2 values ( 123 * 1e20 + 123*1e-20 ) ; 1 row created. ops$tkyte@ORA10GR1> set numformat 999999999999999999999999.999999999999999999999999 ops$tkyte@ORA10GR1> select num_col, 123*1e20, 123*1e-20 from t; NUM_COL -------------------------------------------------- 123*1E20 -------------------------------------------------- 123*1E-20 -------------------------------------------------- 12300000000000000000000.000000000000000000000000 12300000000000000000000.000000000000000000000000 .000000000000000001230000 As you can see, when we put together a very large number (123*1e20) and a very small number (123*1e-20), we lost precision because this arithmetic requires more than 38 digits of precision. The large number by itself can be faithfully represented, as can the small number, but the result of the larger minus the smaller cannot. We can verify this is not just a display/formatting issue as follows: ops$tkyte@ORA10GR1> select num_col from t where num_col = 123*1e20; NUM_COL -------------------------------------------------- 12300000000000000000000.000000000000000000000000 The value in NUM_COL is equal to 123*1e20, and not the value we attempted to insert.

CHAPTER 12 ■ DATATYPES 505<br />

• BINARY_DOUBLE: This is an IEEE native double-precision floating-point number. On disk<br />

it will consume 9 bytes of storage: 8 fixed bytes for the floating-point number <strong>and</strong><br />

1 length byte. It is capable of storing numbers in the range of ~ ± 10 308.25 with 13 digits<br />

of precision.<br />

As you can see from this quick overview, the <strong>Oracle</strong> NUMBER type has significantly larger<br />

precision than the BINARY_FLOAT <strong>and</strong> the BINARY_DOUBLE types, but a much smaller range than<br />

the BINARY_DOUBLE. That is, you can store numbers very precisely with many significant digits<br />

in a NUMBER type, but you can store much smaller <strong>and</strong> larger numbers in the BINARY_FLOAT <strong>and</strong><br />

BINARY_DOUBLE types. As a quick example, we can create a table with the various datatypes in<br />

them <strong>and</strong> see what is stored given the same inputs:<br />

ops$tkyte@ORA10GR1> create table t<br />

2 ( num_col number,<br />

3 float_col binary_float,<br />

4 dbl_col binary_double<br />

5 )<br />

6 /<br />

Table created.<br />

ops$tkyte@ORA10GR1> insert into t ( num_col, float_col, dbl_col )<br />

2 values ( 1234567890.0987654321,<br />

3 1234567890.0987654321,<br />

4 1234567890.0987654321 );<br />

1 row created.<br />

ops$tkyte@ORA10GR1> set numformat 99999999999.99999999999<br />

ops$tkyte@ORA10GR1> select * from t;<br />

NUM_COL FLOAT_COL DBL_COL<br />

------------------------ ------------------------ ------------------------<br />

1234567890.09876543210 1234567940.00000000000 1234567890.09876540000<br />

Note that the NUM_COL returns the exact number we provided as input. There are fewer<br />

than 38 significant digits in the input number (I supplied a number with 20 significant digits),<br />

so the exact number is preserved. The FLOAT_COL, however, using the new BINARY_FLOAT type,<br />

was not able to accurately represent this number. In fact, it preserved only 7 digits accurately.<br />

The DBL_COL faired much better, accurately representing the number in this case out to 17 digits.<br />

Overall, though, this should be a good indication that the BINARY_FLOAT <strong>and</strong> BINARY_DOUBLE<br />

types will not be appropriate for financial applications! If you play around with different values,<br />

you’ll see different results:<br />

ops$tkyte@ORA10GR1> delete from t;<br />

1 row deleted.<br />

ops$tkyte@ORA10GR1> insert into t ( num_col, float_col, dbl_col )<br />

2 values ( 9999999999.9999999999,<br />

3 9999999999.9999999999,

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!