2010-06-14 128 views
0

我有一个UIPicker,用户输入一个指定的时间(即13:00,13:01,13:02等) - 这决定了他们的分数。一旦他们点击按钮,就会通过这个“if-else”声明确定的分数。一切似乎都在大部分时间都有效 - 但我正在发生一些不稳定的行为。这是代码:iPhone在'if'语句上产生奇怪的结果

//Gets my value from the UIPicker and then converts it into a format that can be used in the 'if' statement.  
    NSInteger runRow = [runTimePicker selectedRowInComponent:2]; 
    NSString *runSelected = [runTimePickerData objectAtIndex:runRow]; 
    NSString *runSelectedFixed = [runSelected stringByReplacingOccurrencesOfString:@":" withString:@"."]; 

    //The actual 'if' statment. 
    if ([runSelectedFixed floatValue] <= 13.00) { 
    runScore = 100; 
} else if ([runSelectedFixed floatValue] <= 13.06) { 
    runScore = 99; 
} else if ([runSelectedFixed floatValue] <= 13.12) { 
    runScore = 97; 
} else if ([runSelectedFixed floatValue] <= 13.18) { 
    runScore = 96; 
} else if ([runSelectedFixed floatValue] <= 13.24) { 
    runScore = 94; 
} else if ([runSelectedFixed floatValue] <= 13.30) { 
    runScore = 93; 
} else if ([runSelectedFixed floatValue] <= 13.36) { 
    runScore = 92; 
} else if ([runSelectedFixed floatValue] <= 13.42) { 
    runScore = 90; 
} else if ([runSelectedFixed floatValue] <= 13.48) { 
    runScore = 89; 
} else if ([runSelectedFixed floatValue] <= 13.54) { 
    runScore = 88; 
} 

现在,当我测试程序时,我会得到预期的结果,当我选择'13:00'这是'100'。当我选择'13:01和13:05'之间的所有时间时,我也会得到'99'的预期结果。但是,当我选择'13:06'时,它给了我'97'的分数。 '13:07到13:12'我也得到了'97'的分数 - 这是我们期望的结果。为什么我会在'13:12'上获得'97'的权利,但'13:06'上没有获得'99'的权利?这可能是内存泄漏或什么?

+0

您是否尝试过记录'[runSelectedFixed floatValue]'?机会是你的浮动不*精确* 13.06,但略多...... – 2010-06-14 16:23:21

回答

0

你为什么不而不是将其转换为整数? 例如

NSString *runSelectedFixed = [runSelected stringByReplacingOccurrencesOfString:@":" withString:@""]; 

..

+0

这似乎工作:) – startuprob 2010-06-14 21:32:10

4

不,不是内存泄漏,而是浮点数的工作原理。并非每个有理数都可以通过浮点准确表示。有些数字比其他数字更准确。这是有据可查else where

你会过得更好分裂一次进入整数小时和分钟..

NSArray *components = [@"13:42" componentsSeparatedByString:@":"] 
int hrs = [[components objectAtIndex:0] intValue]; 
int mins = [[components objectAtIndex:1] intValue]; 
0

你是如何转换时间(13:06)到浮动(13.06)? 6/60ths = 0.1,这会导致你看到的结果。我猜这是真正的原因,但一个好的解决方案将与@mustISignUp的建议相同。

1

当您在源代码中输入原始浮点数时,它假定为double。当您将其与[runSelectedFixed floatValue](它是float类型)进行比较时,编译器必须首先将您的float转换为double,然后进行比较。

由于浮点数不能完全表示所有基数为10的数字,因此您的值将在内部四舍五入为最接近的浮点表示形式。例如,当你输入13.06时,float表示可能实际上是13.058(仅仅是一个理论的例子,你实际上比这更精确)。由于double具有更高的精度,因此当您输入13.06时,它可能会保留13.059。因此,一旦你比较了两者,你不会总是得到你期望的结果。请务必阅读the Wikipedia article on floating point,以了解浮点代码的局限性和正确使用方法。

通过在每个文本的末尾添加f,可以使代码中的所有浮点数大于float。例如:

} else if ([runSelectedFixed floatValue] <= 13.06f) { 

这将使您的所有数字保持相同的精度并帮助避免您在上面看到的问题。但是,你不应该使用一个100行的if-else块在完成什么可以用一个简单的公式来完成:

int runScore = 100 - (int)(([runSelectedFixed floatValue] - 13.0f)/0.06f); 

添加边界检查为适合您的代码。同时考虑先将mustSeignFixed分解为hrs和minutes分量,如mustISignUp建议的那样。