【问题标题】:Java parseFloat seems to be acting inconsistentlyJava parseFloat 似乎行为不一致
【发布时间】:2009-11-25 05:54:39
【问题描述】:

我确信这与我对行为的理解有关,而不是 parseFloat 的任何不一致的操作,但请耐心等待...

如果我以“IDCODE: (3.5)”格式输入,其中IDCODE可能是几个不同的预定义字符串,并且保证总是有括号,也保证括号之间有一个数字

我正在尝试将所有输入消化到 IDCODE 存储桶中并对值进行总计,因此需要抓取括号之间的任何内容并将其转换为浮点数以便我可以对其进行求和

为什么以下不起作用?

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 ) ) ) );
}

(抛出数字格式异常)

以下操作在哪里起作用

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 );
}

这对我来说似乎很奇怪 - 我保存到临时变量中造成的差异是什么?

【问题讨论】:

  • 抛出异常时input是什么。
  • 为什么这些循环中的任何一个(除非失败)都不会永远循环?你永远不会改变input,所以如果循环通过一次,它就永远不会结束。这表明您在每种情况下都删除了一些代码,并且您删除的代码可能包含对为什么一个表单失败而另一个表单成功的解释!-)
  • 抱歉 - 只是代码的一个片段 - 不应该把结尾括号放在那里 - 在这两种情况下输入是相同的 - 这就是我感到困惑的原因
  • @Georgie,我相信你的话,这两种情况都是一样的。但我还是想知道它是什么
  • @Georgie - 这是极不可能的。 Java 根本不能那样工作。在“直接”情况下,您很可能没有传递您认为正在传递的子字符串。

标签: java string


【解决方案1】:

当您的代码没有按您认为的那样工作时,是时候进行一些好的老式调试了。比起这里一百个人的建议,你会从中得到更多的好处,除非建议当然是做一些好的老式调试:-)

将您的非工作更改为:

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 ) ) ) );

然后让我们知道输出是什么,尽管您很有可能自己会发现问题。

那些println 语句应该几乎涵盖所有可以想象的问题,如果它实际上在该代码中。

例如下面的项目:

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 ) ) )) + "]");
    }
}

给我:

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

特别是,最后一行打印出来对我来说没问题,这让我相信您显示的代码没有任何问题。我认为问题出在其他地方。

【讨论】:

【解决方案2】:

真正的问题不在于 parseFloat。这是您使用包含数字之前和/或之后的字符或空字符串的字符串参数调用它。

问题中没有足够的代码来弄清楚到底发生了什么,但如果我试图解决这个问题,我要么使用调试器单步执行代码,要么添加一些 System.err.println(...) 语句。尤其要关注传递给parseFloat 的字符串中的确切内容。

【讨论】:

  • 不幸的是,单步不是一个选项——我将函数作为 jasperreports 中的脚本调用(除非有人可以告诉我如何单步执行被外部调用的代码)但是是的,我希望我可以!跨度>
  • @Georgie - 然后使用println
【解决方案3】:

考虑在解析之前修剪/替换 temp 的前导空格,它们也可能触发异常:

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

//或

tot = tot + Float.parseFloat( temp.replace(" ","") );

【讨论】:

  • no - 请参阅“temp”是 DOES 工作的那个 - 在任何一种情况下它都是相同的子字符串调用,因此它们可能都有空格或两者都没有(我可以说他们绝对不是我所有的输入数据)
  • 你试过 Float.isNaN(temp) 的结果了吗,也许这对你有帮助,但很奇怪为什么它不能从 temp 中工作。
  • Float.parseFloat 使用 Float.valueOf 我认为它会自动调用 trim。
【解决方案4】:

让您的生活更轻松,代码更易于理解且重复更少:

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();
}

将每个通话分开后,您可以轻松地做一些事情: - 检查 *Index 变量上的 -1(表示无效输入) - 对任何值(包括值)执行 System.out.println,这样您就可以轻松查看问题所在(我会执行 System.out.println("value = \"" + value + "\"" );)

要遵循的一个好的规则是永远不要将方法的结果作为方法参数或控制语句传递,当出现问题时,它会使调试变得更加困难。

【讨论】:

    猜你喜欢
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多