Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005
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.
- Page 500 and 501: CHAPTER 11 ■ INDEXES 455 Bitmap j
- Page 502 and 503: CHAPTER 11 ■ INDEXES 457 INSERT a
- Page 504 and 505: CHAPTER 11 ■ INDEXES 459 7 l_last
- Page 506 and 507: CHAPTER 11 ■ INDEXES 461 ops$tkyt
- Page 508 and 509: CHAPTER 11 ■ INDEXES 463 If we co
- Page 510 and 511: CHAPTER 11 ■ INDEXES 465 ops$tkyt
- Page 512 and 513: CHAPTER 11 ■ INDEXES 467 Caveat o
- Page 514 and 515: CHAPTER 11 ■ INDEXES 469 ops$tkyt
- Page 516 and 517: CHAPTER 11 ■ INDEXES 471 Frequent
- Page 518 and 519: CHAPTER 11 ■ INDEXES 473 select *
- Page 520 and 521: CHAPTER 11 ■ INDEXES 475 If you s
- Page 522 and 523: CHAPTER 11 ■ INDEXES 477 we’ll
- Page 524 and 525: CHAPTER 11 ■ INDEXES 479 Predicat
- Page 526 and 527: CHAPTER 11 ■ INDEXES 481 ops$tkyt
- Page 528 and 529: CHAPTER 11 ■ INDEXES 483 ops$tkyt
- Page 530 and 531: CHAPTER 11 ■ INDEXES 485 This dem
- Page 532 and 533: CHAPTER 11 ■ INDEXES 487 SELECT /
- Page 534 and 535: CHAPTER 12 ■ ■ ■ Datatypes Ch
- Page 536 and 537: CHAPTER 12 ■ DATATYPES 491 • TI
- Page 538 and 539: CHAPTER 12 ■ DATATYPES 493 (in th
- Page 540 and 541: CHAPTER 12 ■ DATATYPES 495 That d
- Page 542 and 543: CHAPTER 12 ■ DATATYPES 497 ops$tk
- Page 544 and 545: CHAPTER 12 ■ DATATYPES 499 Table
- Page 546 and 547: CHAPTER 12 ■ DATATYPES 501 The IN
- Page 548 and 549: CHAPTER 12 ■ DATATYPES 503 ops$tk
- Page 552 and 553: CHAPTER 12 ■ DATATYPES 507 NUMBER
- Page 554 and 555: CHAPTER 12 ■ DATATYPES 509 MSG NU
- Page 556 and 557: CHAPTER 12 ■ DATATYPES 511 They a
- Page 558 and 559: CHAPTER 12 ■ DATATYPES 513 ■Not
- Page 560 and 561: CHAPTER 12 ■ DATATYPES 515 Coping
- Page 562 and 563: CHAPTER 12 ■ DATATYPES 517 Note t
- Page 564 and 565: CHAPTER 12 ■ DATATYPES 519 We are
- Page 566 and 567: CHAPTER 12 ■ DATATYPES 521 Format
- Page 568 and 569: CHAPTER 12 ■ DATATYPES 523 ops$tk
- Page 570 and 571: CHAPTER 12 ■ DATATYPES 525 You ca
- Page 572 and 573: CHAPTER 12 ■ DATATYPES 527 month
- Page 574 and 575: CHAPTER 12 ■ DATATYPES 529 DT2-DT
- Page 576 and 577: CHAPTER 12 ■ DATATYPES 531 DT TS
- Page 578 and 579: CHAPTER 12 ■ DATATYPES 533 ops$tk
- Page 580 and 581: CHAPTER 12 ■ DATATYPES 535 Since
- Page 582 and 583: CHAPTER 12 ■ DATATYPES 537 ops$tk
- Page 584 and 585: CHAPTER 12 ■ DATATYPES 539 ops$tk
- Page 586 and 587: CHAPTER 12 ■ DATATYPES 541 suppor
- Page 588 and 589: CHAPTER 12 ■ DATATYPES 543 Concep
- Page 590 and 591: CHAPTER 12 ■ DATATYPES 545 We can
- Page 592 and 593: CHAPTER 12 ■ DATATYPES 547 buffer
- Page 594 and 595: CHAPTER 12 ■ DATATYPES 549 Note t
- Page 596 and 597: CHAPTER 12 ■ DATATYPES 551 13 dbm
- Page 598 and 599: CHAPTER 12 ■ DATATYPES 553 equall
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,