iPhone - округление числа с плавающей запятой не работает

Я не могу добиться округления поплавка.

Все эти вызовы возвращают мне 3,5999999, а не 3,6 для theoTimeoutTrick и theoTimeout.
Как я могу получить это значение 3,6 в NSString AND float vars?

#define minTimeout 1.0
#define defaultNbRetry 5

    float secondsWaitedForAnswer = 20.0;
    float minDelayBetween2Retry = 0.5;

    int theoNbRetries = defaultNbRetry;
    float theoTimeout = 0.0;

    while (theoTimeout < minTimeout && theoNbRetries > 0) {
        theoTimeout = (secondsWaitedForAnswer - (theoNbRetries-1)*minDelayBetween2Retry) / theoNbRetries;
        theoNbRetries--;
    }

    float theoTimeoutTrick = [[NSString stringWithFormat:@"%.1f", theoTimeout] floatValue];
    theoTimeout = roundf(theoTimeout * 10)/10.0;

person Oliver    schedule 25.07.2011    source источник
comment
3.6 нельзя точно представить в двоичном виде с конечным числом цифр.   -  person Kerrek SB    schedule 25.07.2011
comment
@Kerrek SB: я могу понять, но мне все равно. Я должен отобразить 3,6, и это правильное округленное значение. Например, вы когда-нибудь видели такие десятичные знаки на своем банковском счете?   -  person Oliver    schedule 25.07.2011
comment
Я уверен, что мой банковский счет не использует IEEE float для моего баланса! (В основном из-за их ограниченного диапазона :-)). Используйте форматированный вывод для вывода округленного значения.   -  person Kerrek SB    schedule 25.07.2011
comment
@Kerrek SB: О чем вы думаете, когда говорите о форматированном выводе? stringWithFormat не выполняет эту работу?   -  person Oliver    schedule 25.07.2011
comment
Вы форматируете, когда фактически выводите в строку. Все, что я вижу, вы делаете, это назначаете числа с плавающей запятой и целые числа. Где ваша выходная печать?   -  person Kerrek SB    schedule 25.07.2011
comment
В качестве альтернативы используйте NSDecimal и NSDecimalNumber.   -  person tc.    schedule 25.07.2011
comment
Программное обеспечение для обработки денег @Kerrek обычно использует двоично-десятичные числа (BED), которые используют 4 бита для каждой цифры. Однако, если вы попробуете что-то вроде NSLog(@"%f", 3.6);, вы обнаружите, что он действительно печатает 3.60000   -  person    schedule 25.07.2011
comment
@bdares: Да, я уверен, что они используют подходящий десятичный формат. Иначе было бы очень жаль! Я думаю, что в C99 также есть поддержка десятичных чисел с плавающей запятой, но я не знаю об ObjC.   -  person Kerrek SB    schedule 25.07.2011
comment
@Kerrek SB: Objective-C является надмножеством C, поэтому, если вы скажете компилятору использовать C99, это будет применяться как к Objective-C, так и к чистому C.   -  person Peter Hosey    schedule 25.07.2011


Ответы (1)


Из Округление чисел в Objective-C:

float roundedValue = round(2.0f * number) / 2.0f;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setMaximumFractionDigits:1];
[formatter setRoundingMode: NSNumberFormatterRoundDown];

NSString *numberString = [formatter stringFromNumber:[NSNumber numberWithFloat:roundedValue]];
[formatter release];

Это даст вам закругленную строку. Я уверен, вы можете разобрать его обратно в поплавок.

Хорошо, вот немного тестового кода и некоторые результаты:

NSLog(@"%f", round(10*3.56)/10.0);
    =>3.600000
NSLog(@"%f", round(10*3.54)/10.0);
    =>3.500000
NSLog(@"%f", round(10*3.14)/10.0);
    =>3.100000

Ладно, знаешь что? Ваш исходный код работает так, как задумано на моей машине, OSX 10.6 и Xcode 4. Как именно вы видите свой результат?

person Community    schedule 25.07.2011
comment
@Oliver: Вопрос для этого поста заключался в округлении до ближайшего 0,5, поэтому он округлил после умножения на 2, а затем разделил результат на 2. Вы можете использовать [formatter setMaximumFractionDigits:0], если хотите округлить до ближайшего целого числа. - person ; 25.07.2011
comment
Ууууу... Я имею в виду... Ууууу! Какого хрена... Ну, это работает не так хорошо из-за круглого типа. У меня просто 3,5. Два вопроса: при чем здесь 2.0f? Какую константу NSNumberFormatter я могу использовать для округления десятичного числа с помощью обычного метода (вы знаете, что до 0,5 он округляется в меньшую сторону, а при 0,5 и более - в большую)? - person Oliver; 25.07.2011
comment
Если бы вы потратили пять секунд на поиск NSNumberFormatterRoundDown в документации, вы бы нашли ответ… - person Rob Keniger; 25.07.2011
comment
@bdares: я просто хочу получить 3.6 - person Oliver; 25.07.2011
comment
@Роб Кенигер: Ах, ах, ах. Не работает. Доку я, конечно, читал. Если я установлю float roundedValue = 3,56; Я просто получаю 3,5, где должно быть 3,6. - person Oliver; 25.07.2011
comment
@ Оливер, тебе действительно стоит подумать об этом немного больше. Если первоначальный парень мог округлить до ближайшего (не пола) 0,5, то вы, конечно, можете изменить его код, чтобы получить ближайшее 0,1. Попробуйте умножить на 10, округлить, а потом разделить на 10, прежде чем взять слово? - person ; 25.07.2011
comment
Это НЕ работает. Как вы думаете, почему я спрашиваю? Ты пробовал ? Я просто продолжаю получать значения 3,5 или 3,5999999999. - person Oliver; 25.07.2011
comment
@bdares: я смотрю на вывод через отладчик - person Oliver; 26.07.2011
comment
@Oliver Оливер, я тоже смотрел на это через свой отладчик (иначе я бы не увидел вывод NSLog()). Возможно, вы захотите обновить свой sdk. - person ; 26.07.2011
comment
@bdares: уххх, это актуально. Я проверил обновление два дня назад. - person Oliver; 26.07.2011