From 445adcb47f03dae8fd0d2a45ee46e4671385cee0 Mon Sep 17 00:00:00 2001 From: Alexander Ljungberg Date: Fri, 10 Jun 2011 11:41:23 -0700 Subject: [PATCH] CPNumberFormatter rounding mode support. --- Foundation/CPDecimal.j | 5 ++++ Foundation/CPNumberFormatter.j | 27 +++++++++++++++++++--- Tests/Foundation/CPNumberFormatterTest.j | 29 ++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/Foundation/CPDecimal.j b/Foundation/CPDecimal.j index c0812f9f8..2c54a333e 100644 --- a/Foundation/CPDecimal.j +++ b/Foundation/CPDecimal.j @@ -72,6 +72,7 @@ CPRoundPlain = 1; CPRoundDown = 2; CPRoundUp = 3; CPRoundBankers = 4; +_CPRoundHalfDown = 5; // Private API rounding mode used by CPNumberFormatter. //Exceptions CPDecimalNumberOverflowException = @"CPDecimalNumberOverflowException"; @@ -1330,6 +1331,10 @@ function CPDecimalRound(result, dcm, scale ,roundingMode) n = result._mantissa[l]; up = (n >= 5); break; + case _CPRoundHalfDown: + n = result._mantissa[l]; + up = (n > 5); + break; case CPRoundBankers: n = result._mantissa[l]; if (n > 5) diff --git a/Foundation/CPNumberFormatter.j b/Foundation/CPNumberFormatter.j index 89d46e7cc..806df5c04 100644 --- a/Foundation/CPNumberFormatter.j +++ b/Foundation/CPNumberFormatter.j @@ -23,6 +23,7 @@ @import @import +@import CPNumberFormatterNoStyle = 0; CPNumberFormatterDecimalStyle = 1; @@ -31,6 +32,14 @@ CPNumberFormatterPercentStyle = 3; CPNumberFormatterScientificStyle = 4; CPNumberFormatterSpellOutStyle = 5; +CPNumberFormatterRoundCeiling = CPRoundUp; +CPNumberFormatterRoundFloor = CPRoundDown; +CPNumberFormatterRoundDown = CPRoundDown; +CPNumberFormatterRoundUp = CPRoundUp; +CPNumberFormatterRoundHalfEven = CPRoundBankers; +CPNumberFormatterRoundHalfDown = _CPRoundHalfDown; +CPNumberFormatterRoundHalfUp = CPRoundPlain; + /*! @ingroup foundation @class CPNumberFormatter @@ -41,8 +50,19 @@ CPNumberFormatterSpellOutStyle = 5; */ @implementation CPNumberFormatter : CPFormatter { - CPNumberFormatterStyle _numberStyle @accessors(property=numberStyle); - CPString _perMillSymbol @accessors(property=perMillSymbol); + CPNumberFormatterStyle _numberStyle @accessors(property=numberStyle); + CPString _perMillSymbol @accessors(property=perMillSymbol); + CPNumberFormatterRoundingMode _roundingMode @accessors(property=roundingMode); +} + +- (id)init +{ + if (self = [super init]) + { + _roundingMode = CPNumberFormatterRoundHalfUp; + } + + return self; } - (CPString)stringFromNumber:(CPNumber)number @@ -52,7 +72,8 @@ CPNumberFormatterSpellOutStyle = 5; { case CPNumberFormatterDecimalStyle: var dcmn = [CPDecimalNumber numberWithFloat:number], - numberHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:CPRoundPlain scale:3 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES]; + roundingMode = [self roundingMode], + numberHandler = [CPDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundingMode scale:3 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES]; dcmn = [dcmn decimalNumberByRoundingAccordingToBehavior:numberHandler]; diff --git a/Tests/Foundation/CPNumberFormatterTest.j b/Tests/Foundation/CPNumberFormatterTest.j index d9ad0b89b..05ded5fc9 100644 --- a/Tests/Foundation/CPNumberFormatterTest.j +++ b/Tests/Foundation/CPNumberFormatterTest.j @@ -16,4 +16,33 @@ [self assert:@"122,344.456" equals:formattedNumberString]; } +- (void)testRoundingMode +{ + var numberFormatter = [[CPNumberFormatter alloc] init], + formattedNumberString; + [numberFormatter setNumberStyle:CPNumberFormatterDecimalStyle]; + + [numberFormatter setRoundingMode:CPNumberFormatterRoundUp]; + formattedNumberString = [numberFormatter stringFromNumber:[CPNumber numberWithFloat:123.5672]]; + [self assert:@"123.568" equals:formattedNumberString]; + + [numberFormatter setRoundingMode:CPNumberFormatterRoundDown]; + formattedNumberString = [numberFormatter stringFromNumber:[CPNumber numberWithFloat:123.5679]]; + [self assert:@"123.567" equals:formattedNumberString]; + + [numberFormatter setRoundingMode:CPNumberFormatterRoundHalfEven]; + formattedNumberString = [numberFormatter stringFromNumber:[CPNumber numberWithFloat:123.5675]]; + [self assert:@"123.568" equals:formattedNumberString]; + formattedNumberString = [numberFormatter stringFromNumber:[CPNumber numberWithFloat:123.5665]]; + [self assert:@"123.566" equals:formattedNumberString]; + + [numberFormatter setRoundingMode:CPNumberFormatterRoundHalfDown]; + formattedNumberString = [numberFormatter stringFromNumber:[CPNumber numberWithFloat:123.5675]]; + [self assert:@"123.567" equals:formattedNumberString]; + + [numberFormatter setRoundingMode:CPNumberFormatterRoundHalfUp]; + formattedNumberString = [numberFormatter stringFromNumber:[CPNumber numberWithFloat:123.5675]]; + [self assert:@"123.568" equals:formattedNumberString]; +} + @end