 ## Decimal arithmetic - FAQ

What is Decimal arithmetic for Java?

Computer systems must provide an arithmetic that gives the results that people expect. This is not available in Java today, so a decimal floating point arithmetic is needed -- one which gives the same results as the arithmetic that people learn at school.

The enhanced BigDecimal class (com.ibm.math.BigDecimal) for Java, available here, provides the necessary arithmetic and is the basis for a proposed enhancement to java.math.BigDecimal. Please see the Java Specification Request for details.

The new class extends the existing BigDecimal class with ANSI X3.274 floating point arithmetic, which has been designed to give the results that people expect. This capability makes it especially easy to add human-oriented arithmetic to applications.

The new BigDecimal class implements immutable arbitrary-precision decimal numbers, with optional exponential notation. The methods of the new class provide the usual operations for fixed and floating point arithmetic, as well as methods for comparison, format conversions, and hashing.

[Top]

What are the advantages of decimal floating point arithmetic?

Most people in the world use decimal floating point arithmetic, where exponents are powers of ten (base ten). However, for historical reasons, most computers have only binary floating point arithmetic, with exponents that are powers of two (base two).

Binary floating point numbers can never represent common decimal values (such as 0.1) exactly, whereas with decimal floating point 0.1 is exactly represented as ten to the power of -1 (10-1).

For example, taking the number 9 and repeatedly dividing by ten yields the following results:

```    Decimal    Binary
-------------------------
0.9        0.9
0.09       0.089999996
0.009      0.0090
0.0009     9.0E-4
0.00009    9.0E-5
0.000009   9.0E-6
9E-7       9.0000003E-7
9E-8       9.0E-8
9E-9       9.0E-9
9E-10      8.9999996E-10
```

Here, the left hand column shows the results delivered by the new BigDecimal class, and the right hand column shows the results obtained by using the Java float datatype. The results from using the double datatype are similar (with more repeated 9s or 0s).

In addition to exact representations of decimal numbers, the floating point arithmetic provided in the new BigDecimal class has many other advantages, including:

• The arithmetic was designed as a full-function decimal floating point arithmetic, directly implementing the rules that people are taught at school. For example, mantissa length information is not lost, so trailing zeros can be correctly preserved in most operations: 1.20 times 2 gives 2.40, not 2.4.
• The precision of the arithmetic is freely selectable by the user, not limited to a choice from one or two alternatives; where necessary, calculations may be made using thousands of digits. The operator definitions, and the current implementation, impose no upper limit on precision (though in practice, memory or processor constraints will bound some calculations).
• A large range of numbers are supported; exponents in the range of E-999999999 through E+999999999 are supported, with a default mantissa precision of nine decimal digits.
• Both scientific (where one digit is shown before the decimal point) and engineering (where the power of ten is a multiple of three) exponential notations are supported.
• The arithmetic operations are robust; there is no "wrap" of integers at certain sizes, and ill-defined or out-of-range results immediately throw exceptions.
• The arithmetic makes no arbitrary distinction between integers and floating point numbers -- the single BigDecimal class can be used for all decimal numbers.
• The arithmetic was developed over several years, based directly on user feedback and requirements, and in consultation with professional mathematicians and data processing experts. It has been heavily used for over 16 years without problems, and was recently reviewed in depth and ratified by the X3J18 committee for ANSI.
• In addition to the new BigDecimal implementation, numerous public-domain and commercial implementations of the arithmetic exist.

[Top]

What disadvantages are there in using decimal arithmetic?

Decimal numbers do not necessarily require more storage or computation than binary numbers, as both the mantissa and exponent can be represented precisely by (binary coded) integers. However, binary floating point is usually implemented by the hardware in a computer, whereas decimal floating point is currently implemented in software in most computers. This means that decimal computations are usually slower than binary operations.

Binary floating point is therefore widely used for "numerically intensive" work where performance is the main concern. For most applications, however, arithmetic performance is not a significant issue, so using decimal floating point avoids anomalies and will give results that match human expectations.

[Top]

Why is the new BigDecimal class better than the old one?

The existing BigDecimal class provides only a minimal fixed point decimal arithmetic capability (please see the Java Specification Request for details of specific problems).

The new BigDecimal class adds:

• new function, including: floating point arithmetic, support for exponential notation (both scientific and engineering), new operators (integer divide, power, and remainder), formatting, and additional conversions.
• efficient control of the arithmetic context, using simple MathContext objects.
• easier programming, with no need for manual accounting of scale, precision, and exponents, along with additional utility methods, etc.
• improved robustness, for example, decapitated conversions raise an exception rather than quietly losing the most significant digits.

In addition, the new BigDecimal uses significantly fewer resources for common operations:

• it is typically 4-5 times faster than the Java 2 java.math.BigDecimal for common operations
• significantly fewer objects are allocated by constructors. For example, to construct a BigDecimal object from the string "2.5" involves the creation of 13 temporary objects with the existing BigDecimal class, but only one with the new class. This makes it up to 23 times faster. If the original string is held in a char array, then no temporary objects are constructed.

The new class is still relatively small, despite the increased function -- at 22,800 bytes, including line number information, it's smaller than the existing BigInteger class (even though the latter makes use of native methods).

[Top]

Is the new BigDecimal compatible with the old one?

Yes. All the methods from the java.math.BigDecimal class are available, and work in the same way. If you already use that BigDecimal class you can probably simply change the import statement:

```    import java.math.*;
```
to
```    import com.ibm.math.*;
```
to access the new classes without changing any other code.

There are some very minor differences, as described in the detailed documentation. For example, the new class can construct BigDecimal objects from strings using exponential notation without throwing an exception.

Apart from the documented differences, and the different package name, the new class passes the relevant tests in the Java Compatibility Kit (JCK).

[Top]

What level of Java do I need?

The new BigDecimal class is intended for use with Java 1.2 (also known as Java 2). Specifically, it implements the java.lang.Comparable interface which is used for sorting in Java 1.2 (this is the only Java 1.2 dependency).

The new class can be used with Java 1.1 if the java.lang.Comparable interface is available in the Java 1.1 environment (for example, if it is copied from a Java 1.2 environment, or re-created). The Comparable interface is simply:

```    package java.lang;
public interface Comparable {
public abstract int compareTo(Object anObject);
}
```
The package also includes decimal1.jar, which contains the two classes but without the reference to the Comparable interface. This should be suitable for use on Java 1.1.x platforms.

[Top]

How do I install the new BigDecimal class, so I can use it?

In brief:

2. Unzip the file into a convenient directory.
3. Add the file decimal.jar to your CLASSPATH setting, or import it into your development environment.
Please see your Java installation instructions for details on how to change your classpath.

You should now be able to compile and run the demonstration application.

[Top]

How do I report bugs?

Please send mail describing the problem to mfc@speleotrove.com.

Please include compilable source code for a sample class (as small as possible) that demonstrates the problem.

[Top]

Where do I find out more?

The documentation for the new BigDecimal and MathContext classes covers the rationale for, and design of, the new classes, in addition to including complete details of the methods and constants available. The documentation is included in the package as decimal.pdf.

There is also a small demonstration application which illustrates how the new BigDecimal class is used.

[Top]