This discussion is archived
7 Replies Latest reply: Jan 7, 2013 3:19 AM by Kayaman RSS

double into a StringBuilder.

870083 Newbie
Currently Being Moderated
My program carries out a number of calculations using doubles and by the end exports the results into a text file. I noticed however that the values are slightly incorrect for example: 0.01 instead of 0.0 or -0.552 instead of -0.55, this problem happens with almost all my values!

I'm aware that floating point primities can't represent every number but I am only working with a very low number of decimal places (upto 3) so I placed some 'System.out.println()'s to track down where the values are going wrong. I noticed that the calculations and all the values are all correct but as soon as they are passed into a StringBuilder eg. sb.append(number). the numbers are corrupted.

Could anyone explain to me how to fix this problem or what is going on? I don't just want to round off the extra number because I do want to keep 3 decimal places and I don't want to replace double with BigDecimal because I have to carry out ALOT of calculations so I don't want to slow things down (I also think it would make the code less readable).

Any help appriciated,

Thanks.
  • 1. Re: double into a StringBuilder.
    EJP Guru
    Currently Being Moderated
    Use a java.text.DecimalFormat .
  • 2. Re: double into a StringBuilder.
    870083 Newbie
    Currently Being Moderated
    Thanks for the reply.

    I quickly looked up the documentation and I believe I have used them acouple of times before for rounding to 3 decimal places for example.
    It's probably my lack of knowledge but I don't see how it can help me and I still don't understand why the numbers are represented perfectly as doubles but are messed up when passed into a StringBuilder? I know if you pass a number into BigDecimal as a string (eg "123.456") it keeps it's values but as a double it changes to its true representation, I tried to have a dig around and see if its something similar to this which is causing the problem. The problem is I need to do calculations first as doubles so conversation to a String needs to be done at some point.
    I also can't just 'round off' the third digit because in some cases when the correct value has a third digit I want to keep it and there is no real way of me being able to tell when that is the case.

    Thanks.
  • 3. Re: double into a StringBuilder.
    EJP Guru
    Currently Being Moderated
    The numbers aren't represented perfectly as doubles, and you have no way of proving otherwise that doesn't invoke conversion to decimal, which is the actual problem in the first place, so it is a circular argument. What you are seeing is the result of converting imprecise floating point to decimal in an uncontrolled way. You need to take control of that process and that's why you should use DecimalFormat.
  • 4. Re: double into a StringBuilder.
    870083 Newbie
    Currently Being Moderated
    Thanks for the reply, after abit of a think it clicked what you were saying and I think I understand what you mean. You need to take control of how the number is formatted and not leave it to be formatted by something else because you can end up with strange output.

    I have tried it and it now works, thank you. I'm going to make it a habit of always formatting numbers before I output them to anything. It's a stupid mistake I shouldn't have made but I'm good at learning the hard way!
  • 5. Re: double into a StringBuilder.
    gimbal2 Guru
    Currently Being Moderated
    Technical wrote:
    It's a stupid mistake I shouldn't have made but I'm good at learning the hard way!
    Its not a mistake, you just started to understand something which previously you did not. The fact that you accept the understanding is exactly the opposite of a mistake.
  • 6. Re: double into a StringBuilder.
    983267 Newbie
    Currently Being Moderated
    Rather than using double as a datatype, use java.math.BigInteger. This may solve your problem and it won't show incorrect values.
  • 7. Re: double into a StringBuilder.
    Kayaman Guru
    Currently Being Moderated
    980264 wrote:
    Rather than using double as a datatype, use java.math.BigInteger. This may solve your problem and it won't show incorrect values.
    Your first post, and you chose to answer wrong.

    BigDecimal would be the answer (absolute requirement, when dealing with monetary values for example), and you still need to pay attention to the scale as well as rounding.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points