#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2010
    Posts
    5
    Rep Power
    0

    Error converting String to float


    I thought the conversion from String to float would be very straightforward, but there is something going on here I don't understand.

    When I run the following code:

    <font size=2><pre>
    String s = "834776.91";
    System.out.println( "s = " + s);

    float f = new Float(s + "f").floatValue();
    System.out.println( "f = " + f);

    double d = new Double(s + "d").doubleValue();
    System.out.println( "d = " + d);
    </pre></font>

    I get the following output:

    <font size=2><pre>
    s = 834776.91
    f = 834776.94
    d = 834776.91
    </pre></font>

    Does anyone know why the value of f is ending up 834776.94 instead of 834776.91 ?

    Thanks for any insight here!
  2. #2
  3. Feelin' Groovy
    Devshed Supreme Being (6500+ posts)

    Join Date
    Aug 2001
    Location
    WDSMIA
    Posts
    10,135
    Rep Power
    5054
    I suspect your result has to do with both rounding and float precision. The bigger the int part of a float, the less precise the fractional part must be. There are only 32 bits in a float, after all!

    Java Code:
    float f = 834776.91f;
    System.out.printf("%f%n", f);   // 834776.937500
    System.out.printf("%.4f%n", f); // 834776.9375
    System.out.printf("%.2f%n", f); // 834776.94


    For more information, check out: What Every Computer Scientist Should Know About Floating-Point Arithmetic.

    ~

    Comments on this post

    • codeJ agrees
    Yawmark
    class Sig{public static void main(String...args){\u0066or(int
    \u0020$:"v\"ʲ\"vΤ\"".to\u0043h\u0061rArray()
    )System./*goto/*$/%\u0126//^\u002A\u002Fout.print((char)(($>>
    +(~'"'&'#'))+('<'>>('\\'/'.')/\u002Array.const(~1)\*\u002F)));}}
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2010
    Posts
    5
    Rep Power
    0
    Thanks Yawmark -- I can see that now.

    I did look at the write-up you pointed me too regarding floating point arithmetic. Most of it was over my head, but the core of it in this situation seems to be the fractional part. The example about storing the decimal value 0.1 in a finite number of binary bits (no matter how many bits!) made this very clear.

    I stumbled across this because I was using NumberFormat to represent a money amount -- stored as a number in Oracle, and returned as String -- as currency, and NumberFormat.format takes a double. Now I see that if the strings contain fractional parts, there is the potential for rounding whether I use a float or a double, depending, as you said, on the size of the int part. I could use BigDecimal, but then I don't know how to have NumberFormat represent this as currency, although because we only deal with US dollars, it is not difficult to do by hand.

    Anyway, thanks very much!
  6. #4
  7. Feelin' Groovy
    Devshed Supreme Being (6500+ posts)

    Join Date
    Aug 2001
    Location
    WDSMIA
    Posts
    10,135
    Rep Power
    5054
    You're welcome. As a related aside, the float and double data types should not be used for financial applications.

    http://martinfowler.com/eaaCatalog/money.html

    ~
    Yawmark
    class Sig{public static void main(String...args){\u0066or(int
    \u0020$:"v\"ʲ\"vΤ\"".to\u0043h\u0061rArray()
    )System./*goto/*$/%\u0126//^\u002A\u002Fout.print((char)(($>>
    +(~'"'&'#'))+('<'>>('\\'/'.')/\u002Array.const(~1)\*\u002F)));}}
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2010
    Posts
    5
    Rep Power
    0
    Hi Yawmark,

    I took a look at the link -- there seems to be pretty universal agreement that float or data primitives are not suitable for money amounts. Some people recommend using BigDecimal and others working with cents using integers.

    Most of our work is within an Oracle database, where the NUMBER datatype serves us quite well for money amounts. In this particular application, however, a jsp is used to render such an amount as currency. As I said -- for reasons I will omit here -- the number is returned from the database as a string, consisting of an integer part, optionally followed by a decimal point and one or two digits.

    Since this application is small, and involves practically no calculations, but rather only rendering values from the database, I am currently using pretty much the following:
    Code:
    NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
    // strings would actually be retrieved from database
    String val1 = "834776.91";
    String val2 = "1234567898765432112345678987654321.91";
    // following would actually be jsp expressions
    System.out.println( nf.format( new BigDecimal(val1) ) );
    System.out.println( nf.format( new BigDecimal(val2) ) );
    The article (above ) says that using BigDecimal is a bad bad idea for money amounts, but I'm not sure why, other than for performance reasons, which in this app are insignificant. I am not sure why using this construct works better, but it seems (so far) to be more likely to give accurate representations, even of unrealistically large numbers. I do have to admit, I am not entirely comfortable with this, because there is no format(Object) method in NumberFormat, so I suppose the BigDecimal is first being converted to double. The construct above, using implicit conversion, gives the intended results (for the examples), but if I use explicit conversion -- BigDecimal.doubleValue() -- rounding occurs for the larger number:

    Code:
    System.out.println( nf.format( new BigDecimal(val1).doubleValue() ) );
    System.out.println( nf.format( new BigDecimal(val2).doubleValue() ) );
    All of the numbers we are dealing with are less than a billion ($1,000,000,000.00). Do you see an issue with my using BigDecimal and implicit conversion in the call to NumberFormat.Format()? If you agree with this article , do you know of any examples of taking such a string and converting it to cents and then using integers?

    Thanks for any thoughts you have regarding this. It so sucks that Oracle bought Sun
  10. #6
  11. AYBABTU
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jul 2004
    Location
    Here or There
    Posts
    1,256
    Rep Power
    376
    The class NumberFormat is an extension of the class Format. This superclass has a method format(Object) which calls a 3 parameter format method of the extending class:
    java Code:
    public final String format (Object obj) {
        return format(obj, new StringBuffer(), new FieldPosition(0)).toString();
    }


    While you might think you're using an instance of NumberFormat class, this method:
    java Code:
    NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);

    actually gives you an instance of java.text.DecimalFormat.

    When you take a closer look at the above mentioned format method in DecimalFormat:

    java Code:
        public final StringBuffer format(Object number,
                                         StringBuffer toAppendTo,
                                         FieldPosition pos) {
            if (number instanceof Long || number instanceof Integer ||
                       number instanceof Short || number instanceof Byte ||
                       number instanceof AtomicInteger ||
                       number instanceof AtomicLong ||
                       (number instanceof BigInteger &&
                        ((BigInteger)number).bitLength () < 64)) {
                return format(((Number)number).longValue(), toAppendTo, pos);
            } else if (number instanceof BigDecimal) {
                return format((BigDecimal)number, toAppendTo, pos);
            } else if (number instanceof BigInteger) {
                return format((BigInteger)number, toAppendTo, pos);
            } else if (number instanceof Number) {
                return format(((Number)number).doubleValue(), toAppendTo, pos);
            } else {
                throw new IllegalArgumentException("Cannot format given Object as a Number");
            }
        }
    You can see on line 11 and 12 that DecimalFormat has a method specific for formatting a BigDecimal. After this off course there is a whole lot more code, but trust me, doubleValue() of BigDecimal is not called once.

    Another hint that NumberFormat does not implicitly call doubleValue() of BigDecimal is that doubelValue() gives you
    Code:
    1.2345678987654321E33
    There is no way Format can dream up the remaining digits after this...


    (First post in years, got to get me a new avatar)
    Last edited by wsa1971; September 24th, 2010 at 06:14 PM.
    A common mistake people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.
    Douglas Adams
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2010
    Posts
    5
    Rep Power
    0
    Thanks very much wsa1971 -- that was an excellent explanation of what is going on here, as well as a good lesson for me in how to dig deeper (into inherited behavior as well as source code) to solve such problems! Help like this from you and Yawmark is very much appreciated :-)
  14. #8
  15. AYBABTU
    Devshed Beginner (1000 - 1499 posts)

    Join Date
    Jul 2004
    Location
    Here or There
    Posts
    1,256
    Rep Power
    376
    You're welcome.
    A common mistake people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.
    Douglas Adams
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    1
    Rep Power
    0

    Cool Complixe Code


    Hello
    every one i am new in Java Programming, how i need to convert this ( y=x2+6x+5 and second one: x2+x3+6x-5 ) to Java Programming code
    there any one who help me regarding this Problem.

    Thanks alot.
  18. #10
  19. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,718
    Rep Power
    348
    You should start a new thread instead of hi-jacking a 3 year old thread.

    What happens when you enter the equation as a statement in a java program?
    Is x2 the name of a variable
    or the product of x and 2. If the product you need to code the multiply operator(*) between the x and the 2: x*2

    What error messages do you get? Please copy the full text of all error messages and paste it here.
    Please copy the full text of your program and paste it here in code tags.

    Also posted at: http://www.javaprogrammingforums.com...tml#post122279
    Last edited by NormR; September 14th, 2013 at 04:58 PM.

IMN logo majestic logo threadwatch logo seochat tools logo