views:

386

answers:

4

I am sure this has more to do with my understanding of the behaviour than any inconsistent action on the part of parseFloat, but bear with me...

if I have input in the format "IDCODE: (3.5)" where IDCODE may be a few different predefined strings, and there is guaranteed to always be brackets, and there is also guaranteed to be a number between the brackets

I'm trying to digest all the input into IDCODE buckets and total the values, and therefore need to grab whatever is in between the brackets and turn it into a float so that I can sum it

why does the following not work?

Float tot = 0;
String idCode = "";
while( !input.isEmpty() )
{
    idCode = GetIdCode(input);
    tot = tot + Float.parseFloat( input.substring( 
                                  input.indexOf( "(", input.indexOf( idCode ) ) + 1, 
                                  input.indexOf( ")", input.indexOf( idCode ) ) ) );
}

(throws a number format exception)

where the following DOES work

Float tot = 0;
String idCode = "";
while( !input.isEmpty() )
{
    idCode = GetIdCode(input);
    String temp = input.substring( 
                  input.indexOf( "(", input.indexOf( idCode ) ) + 1, 
                  input.indexOf( ")", input.indexOf( idCode ) ) );
    tot = tot + Float.parseFloat( temp );
}

this seems strange to me - what is the difference that I have caused by saving into a temporary variable?

A: 

Consider trimming/replacing leading spaces the temp before it gets parsed, they can also trigger the exception:

tot = tot + Float.parseFloat( temp.trim() ); //

//or

tot = tot + Float.parseFloat( temp.replace(" ","") );
jerjer
no - see "temp" is the one which *DOES* work - and it is the same substring call in either case, so they would presumably both have spaces or both not (I can say that they definitely both do not for all of my input data)
hgh
Have you tried the result of Float.isNaN(temp), maybe this can help you, but it so strange why should it not worked form temp.
jerjer
Float.parseFloat uses Float.valueOf which I think call trim automatically.
paxdiablo
+4  A: 

When your code isn't working as you think it should be, it's time for some good old-fashioned debugging. You'll get more benefit out of that than the advice of a hundred people here on SO, unless the advice is to do some good old-fashioned debugging of course :-)

Change your non-working one to:

while( !input.isEmpty() )
{
    idCode = GetIdCode(input);

    // New lines below.
    System.out.println ("input = [" + input + "]");
    System.out.println ("idCode = [" + idCode + "]");

    int i1 = input.indexOf(idCode);
    System.out.println ("offst1 = [" + i1 + "]");

    int i2 = input.indexOf("(",i1);
    System.out.println ("offst2 = [" + i2 + "]");

    int i3 = input.indexOf(")",i1);
    System.out.println ("offst3 = [" + i3 + "]");

    String s1 = input.substring(i2+1,i3);
    System.out.println ("strng1 = [" + s1 + "]");

    float f1 = Float.parseFloat(s1);
    System.out.println ("float1 = [" + f1 + "]");
    // New lines above.

    tot = tot + Float.parseFloat( input.substring( 
        input.indexOf( "(", input.indexOf( idCode ) ) + 1, 
        input.indexOf( ")", input.indexOf( idCode ) ) ) );

then let us know what the output was, although there's a good chance you'll see the problem yourself.

Those println statements should just about cover every conceivable problem, if it's actually in that code.

For example, the following project:

public class xx {
    public static void main(String args[]) {
        String idCode = "CT";
        String input = "fgdfgdg CT: (2.57)";

        System.out.println ("input  = [" + input + "]");
        System.out.println ("idCode = [" + idCode + "]");

        int i1 = input.indexOf(idCode);
        System.out.println ("offst1 = [" + i1 + "]");

        int i2 = input.indexOf("(",i1);
        System.out.println ("offst2 = [" + i2 + "]");

        int i3 = input.indexOf(")",i1);
        System.out.println ("offst3 = [" + i3 + "]");

        String s1 = input.substring(i2+1,i3);
        System.out.println ("strng1 = [" + s1 + "]");

        float f1 = Float.parseFloat(s1);
        System.out.println ("float1 = [" + f1 + "]");

        System.out.println ("full   = [" + Float.parseFloat( input.substring( 
            input.indexOf( "(", input.indexOf( idCode ) ) + 1, 
            input.indexOf( ")", input.indexOf( idCode ) ) )) + "]");
    }
}

gives me:

input  = [fgdfgdg CT: (2.57)]
idCode = [CT]
offst1 = [8]
offst2 = [12]
offst3 = [17]
strng1 = [2.57]
float1 = [2.57]
full   = [2.57]

In particular, the fact that the last line was printed okay for me leads me to believe there's nothing wrong with the code you've shown. Methinks the problem lies elsewhere.

paxdiablo
thanks - I think I need a redface emoticon here - I didn't know how to debug in Java when I'm calling it remotely...thank-you for your patient suggestion =)
hgh
You can remote debug with jpda, see http://java.sun.com/javase/6/docs/technotes/guides/jpda/conninv.html (examples).
wds
+1  A: 

The real problem is not in parseFloat. It is that you are calling it with string arguments that include characters from before and/or after the number, or with empty strings.

There is not enough code included in the question to figure out exactly what is going on, but if I were trying to solve this, I'd either single step the code using a debugger or add some System.err.println(...) statements. In particular, focus on exactly what is in the Strings you are passing to parseFloat.

Stephen C
unfortunately stepping isn't an option - am calling the function as a scriptlet from jasperreports (unless someone can tell me how to step through code being called externally) but yes, I wish I could!
hgh
@Georgie - then use `println`
Stephen C
A: 

Make your life easier, and the code more understandable and less duplicated:

Float tot = 0;

while( !input.isEmpty() )
{
    final String idCode;
    final int    idIndex;
    final int    startIndex;
    final int    endIndex;   
    final String value; 

    idCode     = GetIdCode(input);
    idIndex    = input.indexOf( idCode );
    startIndex = input.indexOf( "(", idIndex) + 1;
    endIndex   = input.indexOf( ")", idIndex);
    value      = input.substring(startIndex, endIndex);
    tot        = tot + Float.parseFloat();
}

Once you have each call separated you can easily do a few things: - check for -1 on the *Index variables (indicating invalid input) - do a System.out.println on any of the values, including the value, so you can easily see what is wrong (I'd do System.out.println("value = \"" + value + "\"");)

A good rule to follow is never pass the result of a method as a method argument or control statement, it makes it much harder to debug when things go wrong.

TofuBeer