停止客观c中的Float值四舍五入

时间:2013-04-15 14:11:49

标签: ios objective-c nsnumberformatter

我必须防止值在小数点后四舍五入。

以下是我使用的代码:

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

5 个答案:

答案 0 :(得分:2)

只需使用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

答案 1 :(得分:2)

如果数学要求精确,我建议使用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];  
}

答案 2 :(得分:1)

他们都是正确的。

首先,我相信你有一个错字 - 你错过了%

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

即使你要求打印2个小数位,数学也会给你一个干净的1/10。

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"

这将强制打印所有尾随零

答案 3 :(得分:0)

您可能正在使用“双重”表示,将数字转换为浮点数,或者您可以使用自己的策略进行截断,使用以下函数:

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'

答案 4 :(得分:0)

对我而言,要求显示至少两位小数和最大十进制数。 以下代码对我有用。

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