• Post Reply Bookmark Topic Watch Topic
  • New Topic

NumberFormat rounding problem  RSS feed

 
Andrey Slastenov
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dears,

I am in the beginning of Murach Java Programming (5th Edition) book.
There is example of NumberFormat rounding problem on page 108 (half-even algorithm).

But, after I try an example from the book: (InvoiceApp), I didn't find any problem with rounding.

My program code:


expected results, according to the book explanation:


but I am getting:


I am using Java 9 and Netbeans 9.

Some one can explain me, why I didn't get any rounding problem like book mention? Is there rounding algorithm change in NumberFormat class?
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
rounding problem like book mention

Can you post examples of the rounding problems the book says you should get?
Be sure to add comments to the lines of the output that shows the problems.
 
Andrey Slastenov
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Norm Radder wrote:
rounding problem like book mention

Can you post examples of the rounding problems the book says you should get?
Be sure to add comments to the lines of the output that shows the problems.


Okey, the first they mention about this problem on page 104:
When you use the format() method of a NumberFormat object, the numbers are automatically rounded using a technique called half-even. This technique rounds up if the preceding digit is odd, but rounds down if the preceding digit is even. U, for example, the currency format is used for a value of 123.455, the formatted result is S 123.46, which is what you would expect. But if the value is 123.445, the result is 123.44. Although this is okay for many applications, it can cause problems in others. You'll learn more about this later in this chapter.


After that on page 108:
How to debug a rounding error
The console at the top of figure 3-1 4 shows more output from the Invoice application in figure 3- 13. Here, the results for a subtotal entry of 100.05 don't add up! If the discount amount is $10.00, the total before tax should be $90.05, but it's $90.04. What's causing this error, and how can we fix it?
To determine the cause, you can add debugging statements like the ones shown here. These statements display the unformatted results before the formatted results. For example, if you look at the unformatted results, yuu can begin to figure out what's causing the problem. To start, the discount amount is 10.005, which isn't a valid monetary amounL For most financial applications, this amount should be rounded up to 10.01. However, because of the way the umberFormat class rounds the numbers, the discount amount value of 10.005 is rounded down lo 10.00. Similarly, the rest of the numbers are not valid monetary amounts either, which could lead to more rounding problems.
Although an error like this may be acceptable in some applications, it is unacceptable in most business applications. And for those applications, you need to provide solutions that deliver the results that you want. Imagine getting an invoice that didn't add up!
One solution is lo add code that rounds the results of each calculation to 2 decimal places. That way, the double types store valid monetary values. Then, you can use the NumberFormat class to format these numbers without worrying about it introducing a rounding error. To implement this solution, you can add statements like the shaded statements shown in the second example. Here, the first shaded statement rounds the discountArnount value to 2 decimal places. Then, the second shaded statement rounds the salesTax value to 2 decimal places. It isn't necessary to round the tota!BeforeTax or total variables since the code uses addition and subtraction to calculate these values. As a result, these calculations shouldn't introduce any new decimal places.
Although this solution is adequate for most applications, it uses the double data type, which is a floating-point number that's only designed to store approximate values. In addition, the roundO method of the Math class doesn't give you much control over how the rounding works. So, if you need to be 100% sure that your decimal numbers are exact, or if you need more control over how those numbers are rounded, it's generally considered a best practice to use the BigDecirnal class as described in the next few figures.


and page 109:


but when I start the code from the example (please check my previous message), I didn't face this problem at all. When I try this code with subtotal value of 100.05 I am getting:


So the problem is - rounding mode working not like explained in the book. I am trying to understand why.
 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am getting: 

Are those the expected values?  If not please add a comment showing what is expected.  For example:

Discount amount:  $10.01   <<<<<< This should be $10.00
 
Andrey Slastenov
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Norm Radder wrote:
I am getting: 

Are those the expected values?  If not please add a comment showing what is expected.  For example:

Discount amount:  $10.01   <<<<<< This should be $10.00


Expected:

Enter subtotal: 100.05
Discount percent: 10%
Discount amount: $10.00
Total before tax: $90.04
sales tax, $4.50
Invoice total : $94.55
continue? (y/n):

Real results:

Enter subtotal:   100.05
Discount percent: 10%
Discount amount:  $10.01  <-- should be 10.00
Total before tax: $90.05 <--- should be 90.04
Sales tax:        $4.50
Invoice total:    $94.55



 
Norm Radder
Rancher
Posts: 2240
28
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, thanks.  That is clear now.

Here is a small test program that shows the differences between java 8 and java 7:

Java 8 rounds differently depending on ???
Java 7 always rounded down
 
Andrey Slastenov
Greenhorn
Posts: 4
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Finally, I found the clear explanation for rounding modes. It looks like, that explanation in the book isn't clear enough.

In the book:

When you use the format() method of a NumberFormat object, the numbers are automatically rounded using a technique called half-even. This technique rounds up if the preceding digit is odd, but rounds down if the preceding digit is even, for example, the currency format is used for a value of 123.455, the formatted result is 123.46, which is what you would expect. But if the value is 123.445, the result is 123.44. Although this is okay for many applications, it can cause problems in others. You'll learn more about this later in this chapter.


In the java documentation:
HALF_EVEN

public static final RoundingMode HALF_EVEN
Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor. Behaves as for RoundingMode.HALF_UP if the digit to the left of the discarded fraction is odd; behaves as for RoundingMode.HALF_DOWN if it's even. Note that this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a sequence of calculations. It is sometimes known as "Banker's rounding," and is chiefly used in the USA. This rounding mode is analogous to the rounding policy used for float and double arithmetic in Java.


Link:Enum RoundingMode

 
Knute Snortum
Sheriff
Posts: 4274
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for posting the answer you found back to this thread.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!