2010-06-14 2 views
0

사용자가 지정된 시간 (예 : 13:00, 13:01, 13:02 등)을 입력하여 점수를 결정하는 UIPicker가 있습니다. 그들이 버튼을 누르면 경고가 '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 아니지만 조금 더 ... –

답변

0

왜 대신이 정수로 변환하지 않습니다 .. else where

당신은 정수 시간과 분으로 시간을 분할 더 나을 것을 문서화? 예 :

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

..

+0

이것은 작동하는 것 같습니다 :) – startuprob

4

아니오, 메모리 누수가 아니라 부동 소수점 숫자가 작동하는 방식의 근본적인 측면입니다. 모든 유리수를 플로트로 정확하게 표현할 수있는 것은 아닙니다. 일부 숫자는 다른 숫자보다 정확합니다. 잘

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

어떻게 변환하는 시간 (13시 6분)는 (13.06)을 수레가? 6/60ths = 0.1이며 결과가 나타납니다. 나는 이것이 진짜 원인이라고 생각 하겠지만, 좋은 해결책은 @mustISignUp에 의해 제안 된 것과 같을 것이다.

1

소스 코드에 원시 부동 소수점 숫자를 입력하면 double으로 간주됩니다. 이 값을 float 유형 인 [runSelectedFixed floatValue]과 비교할 때 컴파일러는 먼저 floatdouble으로 변환 한 다음 비교를 수행해야합니다.

부동 소수점 숫자가 모든 기본 -10 숫자를 완벽하게 나타낼 수 없으므로 값은 내부에서 가장 가까운 부동 소수점 표현으로 반올림됩니다. 예를 들어, 13.06을 입력하면 float 표현은 실제로 13.058 일 수 있습니다 (이론적 인 예를 들어, 실제로 이보다 정밀도가 더 높음). double에는 더 많은 정밀도가 있으므로 13.06을 입력하면 13.059을 보유 할 수 있습니다. 따라서 두 가지를 비교 한 후에는 항상 결과를 얻지 못할 것입니다. the Wikipedia article on floating point을 읽고 부동 소수점 코드의 한계와 올바른 사용법을 이해하십시오.

코드의 부동 소수점 숫자를 모두 float 리터럴 이상으로 만들 수 있습니다. 각각의 끝에 f을 추가합니다. 예를 들면 다음과 같습니다.

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

이렇게하면 모든 숫자가 동일한 정밀도로 유지되고 위의 문제를 피할 수 있습니다.

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

가 경계 당신의 코드에 대한 적절한 검사 추가 블록에서 간단한 방정식을 함께 할 수있는 무엇을 달성하는 경우 - 다른 그러나 100 선을 사용하지 말아야합니다. 또한 mustISignUp 제안대로 runSelectedFixed를 hrs 및 minutes 구성 요소로 먼저 분할하는 것을 고려하십시오.

관련 문제