Item 31: Avoid float and double if exact answers are required

Create QR Code In JavaUsing Barcode creation for Java Control to generate, create QR Code 2d barcode image in Java applications.

The float and double types are designed primarily for scientific and engineering calculations They perform binary floating-point arithmetic, which was carefully designed to furnish accurate approximations quickly over a broad range of magnitudes They do not, however, provide exact results and should not be used where exact results are required The float and double types are particularly ill-suited for monetary calculations because it is impossible to represent 01 (or any other negative power of ten) as a float or double exactly

Bar Code Creator In JavaUsing Barcode drawer for Java Control to generate, create bar code image in Java applications.

Effective Java: Programming Language Guide

Read Barcode In JavaUsing Barcode decoder for Java Control to read, scan read, scan image in Java applications.

For example, suppose you have $103 in your pocket, and you spend 42 How much money do you have left Here's a naive program fragment that attempts to answer this question:

Draw QR In Visual C#.NETUsing Barcode maker for VS .NET Control to generate, create QR image in .NET framework applications.

Systemoutprintln(103 - 42);

QR Code Encoder In .NETUsing Barcode generator for ASP.NET Control to generate, create QR-Code image in ASP.NET applications.

Unfortunately, it prints out 06100000000000001 This is not an isolated case Suppose you have a dollar in your pocket, and you buy nine washers priced at ten cents each How much change do you get

Drawing QR Code In VS .NETUsing Barcode creation for .NET Control to generate, create QR Code ISO/IEC18004 image in .NET framework applications.

Systemoutprintln(100 - 9*10);

Encode QR-Code In VB.NETUsing Barcode drawer for .NET framework Control to generate, create QR Code ISO/IEC18004 image in VS .NET applications.

According to this program fragment, you get $009999999999999995 You might think that the problem could be solved merely by rounding results prior to printing, but unfortunately this does not always work For example, suppose you have a dollar in your pocket, and you see a shelf with a row of delicious candies priced at 10, 20, 30, and so forth, up to a dollar You buy one of each candy, starting with the one that costs 10, until you can't afford to buy the next candy on the shelf How many candies do you buy, and how much change do you get Here's a naive program designed to solve this problem:

Draw DataMatrix In JavaUsing Barcode generation for Java Control to generate, create Data Matrix ECC200 image in Java applications.

// Broken - uses floating point for monetary calculation! public static void main(String[] args) { double funds = 100; int itemsBought = 0; for (double price = 10; funds >= price; price += 10) { funds -= price; itemsBought++; } Systemoutprintln(itemsBought + " items bought"); Systemoutprintln("Change: $" + funds); }

Encoding Barcode In JavaUsing Barcode encoder for Java Control to generate, create barcode image in Java applications.

If you run the program, you'll find that you can afford three pieces of candy, and you have $03999999999999999 left This is the wrong answer! The right way to solve this problem is to use BigDecimal, int, or long for monetary calculations Here's a straightforward transformation of the previous program to use the BigDecimal type in place of double:

Encode Bar Code In JavaUsing Barcode creation for Java Control to generate, create bar code image in Java applications.

public static void main(String[] args) { final BigDecimal TEN_CENTS = new BigDecimal("10"); int itemsBought = 0; BigDecimal funds = new BigDecimal("100"); for (BigDecimal price = TEN_CENTS; fundscompareTo(price) >= 0; price = priceadd(TEN_CENTS)) { itemsBought++; funds = fundssubtract(price); } Systemoutprintln(itemsBought + " items bought"); Systemoutprintln("Money left over: $" + funds);

Drawing EAN / UCC - 13 In JavaUsing Barcode generation for Java Control to generate, create GTIN - 13 image in Java applications.

Effective Java: Programming Language Guide

Painting Bar Code In JavaUsing Barcode generator for Java Control to generate, create barcode image in Java applications.

If you run the revised program, you'll find that you can afford four pieces of candy, with $000 left over This is the correct answer There are, however, two disadvantages to using BigDecimal: It's less convenient than using a primitive arithmetic type, and its slower The latter disadvantage is irrelevant if you're solving a single short problem, but the former may annoy you An alternative to using BigDecimal is to use int or long, depending on the amounts involved, and to keep track of the decimal point yourself In this example, the obvious approach is to do all computation in pennies instead of dollars Here's a straightforward transformation of the program just shown that takes this approach:

2 Of 5 Interleaved Printer In JavaUsing Barcode encoder for Java Control to generate, create 2 of 5 Interleaved image in Java applications.

public static void main(String[] args) { int itemsBought = 0; int funds = 100; for (int price = 10; funds >= price; price += 10) { itemsBought++; funds -= price; } Systemoutprintln(itemsBought + " items bought"); Systemoutprintln("Money left over: "+ funds + " cents"); }

Bar Code Generator In Visual Studio .NETUsing Barcode creator for ASP.NET Control to generate, create barcode image in ASP.NET applications.

In summary, don't use float or double for any calculations that require an exact answer Use BigDecimal if you want the system to keep track of the decimal point and you don't mind the inconvenience of not using a primitive type Using BigDecimal has the added advantage that it gives you full control over rounding, letting you select from eight rounding modes whenever an operation that entails rounding is performed This comes in handy if you're performing business calculations with legally mandated rounding behavior If performance is of the essence, if you don't mind keeping track of the decimal point yourself, and if the quantities aren't too big, use int or long If the quantities don't exceed nine decimal digits, you can use int; if they don't exceed eighteen digits, you can use long If the quantities exceed eighteen digits, you must use BigDecimal

Generate Code 128A In C#Using Barcode encoder for .NET framework Control to generate, create Code 128C image in VS .NET applications.

Recognize Code 128 In Visual Studio .NETUsing Barcode decoder for Visual Studio .NET Control to read, scan read, scan image in Visual Studio .NET applications.

Encode Data Matrix In Visual C#Using Barcode generator for .NET framework Control to generate, create Data Matrix image in .NET applications.

Paint ECC200 In Visual Basic .NETUsing Barcode generation for Visual Studio .NET Control to generate, create Data Matrix 2d barcode image in .NET framework applications.