Остановить округление плавающего значения в цели c

Я должен предотвратить округление значения после запятой.

Вот код, который я использую:

NSNumberFormatter* nf = [[[NSNumberFormatter alloc] init] autorelease];
nf.positiveFormat = @"0.###";      
NSString* trimmedValue = [nf stringFromNumber: [NSNumber numberWithFloat:[exRateLabel doubleValue]*amount]];
trimmedValue = [trimmedValue substringToIndex:[trimmedValue length]-1];

В этом случае, если я умножу 1000 * 50,1234, я получу 50123,3984, но должно быть 50123,4.

NSLog(@".2f",50.1234*1000);

В этом случае он показывает правильное значение, но для

NSLog(@".2f",50.1234*123);

он округляет фактическое значение, равное 6165,1782, до 6165,18.


person Sri    schedule 15.04.2013    source источник
comment
умножить на 10000 и т. д., сохранить в целое число. делить на те же 1000 и т.д.   -  person Anoop Vaidya    schedule 15.04.2013
comment
@AnoopVaidya Спасибо за ответ, но для 4999*50.1234 я получаю 250566.891   -  person Sri    schedule 15.04.2013
comment
сначала умножьте 50,1234 на 1000, чтобы округлить   -  person Anoop Vaidya    schedule 15.04.2013


Ответы (5)


Просто используйте double вместо float и правильное правило округления:

NSNumberFormatter* nf = [[NSNumberFormatter alloc] init];
nf.positiveFormat = @"0.###";
nf.roundingMode = NSNumberFormatterRoundFloor;
NSString* trimmedValue = [nf stringFromNumber: [NSNumber numberWithDouble:50.1234*123]];
NSLog(@"trimmedValue: %@", trimmedValue);

И результат:

trimmedValue: 6165.178
person kovpas    schedule 15.04.2013
comment
Привет 4999*50.1234 в этом случае я получаю 250566.88 вместо 250566.87 - person Sri; 15.04.2013
comment
250566,8766 раундов до 250566,88 - person kovpas; 15.04.2013
comment
я не хочу округлять, мне нужно отображать только .87, но отображается .88 - person Sri; 15.04.2013
comment
А, понял. Обновленный ответ. - person kovpas; 15.04.2013

Если математика должна быть точной, я бы предложил использовать NSDecimalNumber.

NSDecimalNumber *myNumber = [[NSDecimalNumber alloc] initWithMantissa:501234 exponent:-4 isNegative:NO]];  
NSDecimalNumber *answer = [self multiplyDecimalNumber:myNumber with:[NSDecimalNumber decimalNumberWithMantissa:1000 exponent:0 isNegative:NO];  
NSLog(@"Answer: %g", floor([answer doubleValue]));

Я сделал быструю оболочку для умножения, я никогда не хотел исключения, ваши потребности могут быть другими:

-(NSDecimalNumber *) multiplyDecimalNumber:(NSDecimalNumber *) lhs with:(NSDecimalNumber *) rhs {  
    NSDecimalNumberHandler *handler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:NSDecimalNoScale raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO];  
    return [lhs decimalNumberByMultiplyingBy:rhs withBehavior:handler];  
}
person user352891    schedule 15.04.2013
comment
привет, его преобразование отлично, но пока я показываю в метке, поскольку .2f снова округляется. Это моя проблема.... - person Sri; 15.04.2013
comment
Тогда кажется, что вы просто недовольны округлением. Если это так, вы можете сделать что-то вроде: floor((50.1234 * 123) * 100) / 100 - это удалит любую точность после второго десятичного знака. Изменить. Сообщение Ману от ~ 50 минут назад содержит удобные функции, если это исправление, которое вы ищете, я бы предложил наградить Ману ответом. - person user352891; 15.04.2013

Они оба правильные.

Во-первых, я считаю, что у вас опечатка - вам не хватает %.

NSLog(@"%.2f", 50.1234*1000); // same as @"%.2f", 50,123.4 = @"50123.4"

математика оставляет вас с чистой 1/10-й, даже если вы просите напечатать 2 десятичных знака.

NSLog(@"%.2f",50.1234*123); // same as @"%.2f", 5,161.1782 = @"5161.18"

вы запрашиваете два десятичных числа, и округление является поведением по умолчанию.

Похоже, форматирование, которое вы действительно хотите использовать, это:

NSLog(@"%.1f", number);

или если вам нужны принудительные две цифры, дополненные нулями, используйте

NSLog(@"%.02", number); // first case would come out @"50123.40"

это заставит печатать все конечные нули

person bshirley    schedule 15.04.2013

вы, вероятно, используете «двойное» представление, приведите число к поплавку или вы можете использовать свою собственную политику для усечения, используя такие функции, как:

float roundUp (float value, int digits) {

    int mod = pow(10, digits);

    float roundedUp = value;
    if (mod != 0) {
        roundedUp = ceilf(value * mod) / mod;
    }

    return roundedUp;
}

float roundDown (float value, int digits) {

    int mod = pow(10, digits);

    float roundedDown = value;
    if (mod != 0) {
       roundedDown = floorf(value * mod) / mod;
    }

    return roundedDown;
}

float nearestf (float value, int digits) {

    int mod = pow(10, digits);

    float nearest = value;
    if (mod != 0) {
        nearest = floorf(value*mod + 0.5) / mod;
    }

    return nearest;
}

«roundUp» должен быть тем, что вам нужно, или попробуйте более общий «nearestf»

person Manu    schedule 15.04.2013

Для меня требовалось показать как минимум два десятичных и максимальное десятичное число. Следующий код работал у меня.

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numberFormatter setMaximumFractionDigits:2];
[numberFormatter setMinimumFractionDigits:2];
[numberFormatter setRoundingMode:NSNumberFormatterRoundDown];
NSString *num = @"123456.019";
NSString *stringFromNumber = [numberFormatter stringFromNumber:[numberFormatter numberFromString:num]];
NSLog(@"check this %@", stringFromNumber);
person Rupesh    schedule 26.05.2016