Search code examples
iphoneobjective-cnsnumberformatter

How to format a number with NSNumberFormatter in DecimalSyle or ScientificStyle depending on the length?


I need format a number with NSNumberFormatter. If number is small (e.g. 0.000001) will be displayed in decimal format 0.000001. If number is large, many decimal, or integer (E.g. 1211345456 or 0.000000011111553242), will be displayed in scientific notation, 1.211 E9.

I have this code (very bad), but not enough for me: (. I think the solution would be in -setPositiveFormat and format patterns #,##0.0000000 and 0.###E+0, any idea?

NSNumberFormatter *formato = [[NSNumberFormatter alloc] init];
    [formato setNumberStyle:NSNumberFormatterDecimalStyle];
    [formato setPositiveFormat:@"#,##0.0000000"];   
    [formato setNegativeFormat:@"-#,##0.0000000"];
    [formato setMaximumFractionDigits:7];
    [formato setMinimumFractionDigits:0];
    [formato setRoundingMode: NSNumberFormatterRoundHalfDown];

    NSString *numero = [formato stringFromNumber:[NSNumber numberWithDouble:valor]];

    //si vale después de formatear y el valor inicial es distinto de 0 se va de rango,
    //por lo tanto usamos notación científica
    if([numero isEqualToString:@"0"] && valor != 0){
        //inicializamos el objeto de nuevo para que no de problemas con setPositiveFormat
        [formato release];
        formato = [[NSNumberFormatter alloc] init];
        [formato setNumberStyle:NSNumberFormatterScientificStyle];
        [formato setMaximumFractionDigits:4];
        [formato setRoundingMode: NSNumberFormatterRoundHalfDown];
        [formato setExponentSymbol:@"e"];
        numero = [formato stringFromNumber:[NSNumber numberWithDouble:valor]] ;
    }

    [formato release];

Solution

  • You could just test the number before you post it and change the number depending on its size:

    if (fabs(number)>10e7 || fabs(number)<10e-7) {
        [self.formatter setNumberStyle:NSNumberFormatterScientificStyle]; 
    }
    else
        [self.formatter setNumberStyle:NSNumberFormatterDecimalStyle];