开发者

ObjC Formatting Decimal places of Float to string

开发者 https://www.devze.com 2023-02-17 01:35 出处:网络
How do I format a float to string so that if the user enters a number that has 2 or less decimal places then it is formatted to have 2 decimal places,开发者_开发技巧 but if the user enters a float tha

How do I format a float to string so that if the user enters a number that has 2 or less decimal places then it is formatted to have 2 decimal places,开发者_开发技巧 but if the user enters a float that has 2 or more decimal places then all decimal places are shown. e.g.

4.1 => 4.10
1 => 1.00
1.358484 => 1.358484

So therefore the formatting is to 2 decimal places or more if needed.

Hope I made sense.


Try something like this.

BOOL requiresExtraPrecision (double num) {
    double roundedToHundredth = round(num * 100.0) / 100.0;
    double diff = num - roundedToHundredth;
    if (diff < 0) diff = 0.0 - diff;
    if (diff < 0.0000001) {
        return NO;
    } else {
        return YES;
    }
}

NSString *formatted (double num) {
    if (requiresExtraPrecision(num)) {
        return [NSString stringWithFormat:@"%F", num];
    } else {
        NSNumberFormatter *formatter = [[[NSNumberFormatter alloc] init] autorelease];
        [formatter setMaximumFractionDigits:2];
        [formatter setMinimumFractionDigits:2];
        return [formatter stringFromNumber:[NSNumber numberWithDouble:num]];
    }
}

As @Carl wrote in a comment to the question, the hard part is deciding when a double needs all of its precision. In this code, I'm assuming that if the double is "close enough" to a rounded number (within a millionth), then we should just display the rounded number.

You might decide to make it stricter (a billionth?) but you'll always have to use some kind of approximation, because some decimals can't be stored precisely as a float. Even though the user may have typed "0.1" at input time, that information is lost when the number is stored as a float.

So, given that you'll have a float that's extremely close to a decimal but not exactly right, you'll have to decide when you think the float is "close enough" to the decimal.

If you need absolute precision (if you're working with money!) then you should consider using an NSDecimal or an NSDecimalNumber instead of a float.


this could work for you:

NSNumber *aFloat = [NSNumber numberWithFloat:1.2]; //try 1.234 ; 1.23 ; 1.2 ; 1. ; 1
NSString *numberString = [aFloat stringValue];
NSRange dot;
dot = [numberString rangeOfString:@"."];
NSString *finalString;
if (dot.location != NSNotFound) {
    NSString *decimals = [numberString substringFromIndex:dot.location + dot.length];
    if (decimals.length<1){ // ends with "."
        finalString = [numberString stringByAppendingString:@"00"];
    }else if (decimals.length<2){ // ends with ".n"
        finalString = [numberString stringByAppendingString:@"0"];
    }else { // 2 or more decimals: no changes
        finalString = numberString;
    }
}else { // no decimals
    finalString = [numberString stringByAppendingString:@".00"];
}
NSLog(@"______._____finalString:%@", finalString );

EDIT (more flexible, it works with variable numbers of decimals):

NSNumber *aFloat = [NSNumber numberWithFloat:1.1235]; //try 1.234 ; 1.23 ; 1.2 ; 1. ; 1
NSString *numberString = [aFloat stringValue];
NSRange dot;
dot = [numberString rangeOfString:@"."];
if (dot.location == NSNotFound) { // no decimals, add a dot
    numberString = [numberString stringByAppendingString:@"."];
    NSLog(@"__added dot___ numberString:%@", numberString );
}
dot = [numberString rangeOfString:@"."];
NSString *decimals = [numberString substringFromIndex:dot.location + dot.length];
//      int initialDecimals = decimals.length;
int numberOfDecimalsTerget = 2;

for (int initialDecimals = decimals.length; initialDecimals<numberOfDecimalsTerget; initialDecimals++) {
    numberString = [numberString stringByAppendingString:@"0"];
}
NSLog(@"__END_._____numberString:%@", numberString );
0

精彩评论

暂无评论...
验证码 换一张
取 消