![]() |
API 0.9.5
|
00001 /* 00002 * CPDecimalNumber.j 00003 * Foundation 00004 * 00005 * Created by Stephen Paul Ierodiaconou 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 00023 // The default global behavior class, created lazily 00024 var CPDefaultDcmHandler = nil; 00025 00032 @implementation CPDecimalNumberHandler : CPObject 00033 { 00034 CPRoundingMode _roundingMode; 00035 short _scale; 00036 BOOL _raiseOnExactness; 00037 BOOL _raiseOnOverflow; 00038 BOOL _raiseOnUnderflow; 00039 BOOL _raiseOnDivideByZero; 00040 } 00041 00042 // initializers 00049 - (id)init 00050 { 00051 return [self initWithRoundingMode:CPRoundPlain 00052 scale:0 00053 raiseOnExactness:NO 00054 raiseOnOverflow:YES 00055 raiseOnUnderflow:YES 00056 raiseOnDivideByZero:YES]; 00057 } 00058 00080 - (id)initWithRoundingMode:(CPRoundingMode)roundingMode scale:(short)scale raiseOnExactness:(BOOL)exact raiseOnOverflow:(BOOL)overflow raiseOnUnderflow:(BOOL)underflow raiseOnDivideByZero:(BOOL)divideByZero 00081 { 00082 if (self = [super init]) 00083 { 00084 _roundingMode = roundingMode; 00085 _scale = scale; 00086 _raiseOnExactness = exact; 00087 _raiseOnOverflow = overflow; 00088 _raiseOnUnderflow = underflow; 00089 _raiseOnDivideByZero = divideByZero; 00090 } 00091 00092 return self; 00093 } 00094 00095 // class methods 00101 + (id)decimalNumberHandlerWithRoundingMode:(CPRoundingMode)roundingMode scale:(short)scale raiseOnExactness:(BOOL)exact raiseOnOverflow:(BOOL)overflow raiseOnUnderflow:(BOOL)underflow raiseOnDivideByZero:(BOOL)divideByZero 00102 { 00103 return [[self alloc] initWithRoundingMode:roundingMode 00104 scale:scale 00105 raiseOnExactness:exact 00106 raiseOnOverflow:overflow 00107 raiseOnUnderflow:underflow 00108 raiseOnDivideByZero:divideByZero]; 00109 } 00110 00117 + (id)defaultDecimalNumberHandler 00118 { 00119 if (!CPDefaultDcmHandler) 00120 CPDefaultDcmHandler = [[CPDecimalNumberHandler alloc] init]; 00121 return CPDefaultDcmHandler; 00122 } 00123 00124 @end 00125 00126 // CPDecimalNumberBehaviors protocol 00127 @implementation CPDecimalNumberHandler (CPDecimalNumberBehaviors) 00128 00134 - (CPRoundingMode)roundingMode 00135 { 00136 return _roundingMode; 00137 } 00138 00143 - (short)scale 00144 { 00145 return _scale; 00146 } 00147 00166 - (CPDecimalNumber)exceptionDuringOperation:(SEL)operation error:(CPCalculationError)error leftOperand:(CPDecimalNumber)leftOperand rightOperand:(CPDecimalNumber)rightOperand 00167 { 00168 switch (error) 00169 { 00170 case CPCalculationNoError: break; 00171 case CPCalculationOverflow: if (_raiseOnOverflow) 00172 [CPException raise:CPDecimalNumberOverflowException reason:("A CPDecimalNumber overflow has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; 00173 else 00174 return [CPDecimalNumber notANumber]; 00175 break; 00176 case CPCalculationUnderflow: if (_raiseOnUnderflow) 00177 [CPException raise:CPDecimalNumberUnderflowException reason:("A CPDecimalNumber underflow has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; 00178 else 00179 return [CPDecimalNumber notANumber]; 00180 break; 00181 case CPCalculationLossOfPrecision: if (_raiseOnExactness) 00182 [CPException raise:CPDecimalNumberExactnessException reason:("A CPDecimalNumber has been rounded off during a calculation. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; 00183 break; 00184 case CPCalculationDivideByZero: if (_raiseOnDivideByZero) 00185 [CPException raise:CPDecimalNumberDivideByZeroException reason:("A CPDecimalNumber divide by zero has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; 00186 else 00187 return [CPDecimalNumber notANumber]; // Div by zero returns NaN 00188 break; 00189 default: [CPException raise:CPInvalidArgumentException reason:("An unknown CPDecimalNumber error has occurred. (Left operand= '" + [leftOperand descriptionWithLocale:nil] + "' Right operand= '" + [rightOperand descriptionWithLocale:nil] + "' Selector= '" + operation + "')") ]; 00190 } 00191 00192 return nil; 00193 } 00194 00195 @end 00196 00197 // CPCoding category 00198 var CPDecimalNumberHandlerRoundingModeKey = @"CPDecimalNumberHandlerRoundingModeKey", 00199 CPDecimalNumberHandlerScaleKey = @"CPDecimalNumberHandlerScaleKey", 00200 CPDecimalNumberHandlerRaiseOnExactKey = @"CPDecimalNumberHandlerRaiseOnExactKey", 00201 CPDecimalNumberHandlerRaiseOnOverflowKey = @"CPDecimalNumberHandlerRaiseOnOverflowKey", 00202 CPDecimalNumberHandlerRaiseOnUnderflowKey = @"CPDecimalNumberHandlerRaiseOnUnderflowKey", 00203 CPDecimalNumberHandlerDivideByZeroKey = @"CPDecimalNumberHandlerDivideByZeroKey"; 00204 00205 @implementation CPDecimalNumberHandler (CPCoding) 00206 00211 - (id)initWithCoder:(CPCoder)aCoder 00212 { 00213 if (self) 00214 { 00215 [self initWithRoundingMode:[aCoder decodeIntForKey:CPDecimalNumberHandlerRoundingModeKey] 00216 scale:[aCoder decodeIntForKey:CPDecimalNumberHandlerScaleKey] 00217 raiseOnExactness:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnExactKey] 00218 raiseOnOverflow:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnOverflowKey] 00219 raiseOnUnderflow:[aCoder decodeBoolForKey:CPDecimalNumberHandlerRaiseOnUnderflowKey] 00220 raiseOnDivideByZero:[aCoder decodeBoolForKey:CPDecimalNumberHandlerDivideByZeroKey]]; 00221 } 00222 00223 return self; 00224 } 00225 00230 - (void)encodeWithCoder:(CPCoder)aCoder 00231 { 00232 [aCoder encodeInt:[self roundingMode] forKey:CPDecimalNumberHandlerRoundingModeKey]; 00233 [aCoder encodeInt:[self scale] forKey:CPDecimalNumberHandlerScaleKey]; 00234 [aCoder encodeBool:_raiseOnExactness forKey:CPDecimalNumberHandlerRaiseOnExactKey]; 00235 [aCoder encodeBool:_raiseOnOverflow forKey:CPDecimalNumberHandlerRaiseOnOverflowKey]; 00236 [aCoder encodeBool:_raiseOnUnderflow forKey:CPDecimalNumberHandlerRaiseOnUnderflowKey]; 00237 [aCoder encodeBool:_raiseOnDivideByZero forKey:CPDecimalNumberHandlerDivideByZeroKey]; 00238 } 00239 00240 @end 00241 00289 @implementation CPDecimalNumber : CPNumber 00290 { 00291 CPDecimal _data; 00292 } 00293 00300 + (id)alloc 00301 { 00302 // overriding alloc means CPDecimalNumbers are not toll free bridged 00303 return class_createInstance(self); 00304 } 00305 00306 // initializers 00311 - (id)init 00312 { 00313 return [self initWithDecimal:CPDecimalMakeNaN()]; 00314 } 00315 00321 - (id)initWithDecimal:(CPDecimal)dcm 00322 { 00323 if (self = [super init]) 00324 _data = CPDecimalCopy(dcm); 00325 00326 return self; 00327 } 00328 00341 - (id)initWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag 00342 { 00343 if (self = [self init]) 00344 { 00345 if (flag) 00346 mantissa *= -1; 00347 00348 _data = CPDecimalMakeWithParts(mantissa, exponent); 00349 } 00350 00351 return self; 00352 } 00353 00361 - (id)initWithString:(CPString)numberValue 00362 { 00363 return [self initWithString:numberValue locale:nil]; 00364 } 00365 00375 - (id)initWithString:(CPString)numberValue locale:(CPDictionary)locale 00376 { 00377 if (self = [self init]) 00378 { 00379 _data = CPDecimalMakeWithString(numberValue, locale); 00380 } 00381 00382 return self; 00383 } 00384 00385 // class methods 00391 + (CPDecimalNumber)decimalNumberWithDecimal:(CPDecimal)dcm 00392 { 00393 return [[self alloc] initWithDecimal:dcm]; 00394 } 00395 00404 + (CPDecimalNumber)decimalNumberWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag 00405 { 00406 return [[self alloc] initWithMantissa:mantissa exponent:exponent isNegative:flag]; 00407 } 00408 00416 + (CPDecimalNumber)decimalNumberWithString:(CPString)numberValue 00417 { 00418 return [[self alloc] initWithString:numberValue]; 00419 } 00420 00430 + (CPDecimalNumber)decimalNumberWithString:(CPString)numberValue locale:(CPDictionary)locale 00431 { 00432 return [[self alloc] initWithString:numberValue locale:locale]; 00433 } 00434 00439 + (id)defaultBehavior 00440 { 00441 return [CPDecimalNumberHandler defaultDecimalNumberHandler]; 00442 } 00443 00449 + (void)setDefaultBehavior:(id <CPDecimalNumberBehaviors>)behavior 00450 { 00451 CPDefaultDcmHandler = behavior; 00452 } 00453 00460 + (CPDecimalNumber)maximumDecimalNumber 00461 { 00462 return [[self alloc] initWithDecimal:_CPDecimalMakeMaximum()]; 00463 } 00464 00471 + (CPDecimalNumber)minimumDecimalNumber 00472 { 00473 return [[self alloc] initWithDecimal:_CPDecimalMakeMinimum()]; 00474 } 00475 00480 + (CPDecimalNumber)notANumber 00481 { 00482 return [[self alloc] initWithDecimal:CPDecimalMakeNaN()]; 00483 } 00484 00489 + (CPDecimalNumber)zero 00490 { 00491 return [[self alloc] initWithDecimal:CPDecimalMakeZero()]; 00492 } 00493 00498 + (CPDecimalNumber)one 00499 { 00500 return [[self alloc] initWithDecimal:CPDecimalMakeOne()]; 00501 } 00502 00503 // instance methods 00511 - (CPDecimalNumber)decimalNumberByAdding:(CPDecimalNumber)decimalNumber 00512 { 00513 return [self decimalNumberByAdding:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; 00514 } 00515 00524 - (CPDecimalNumber)decimalNumberByAdding:(CPDecimalNumber)decimalNumber withBehavior:(id <CPDecimalNumberBehaviors>)behavior 00525 { 00526 var result = CPDecimalMakeZero(), 00527 error = CPDecimalAdd(result, [self decimalValue], [decimalNumber decimalValue], [behavior roundingMode]); 00528 00529 if (error > CPCalculationNoError) 00530 { 00531 var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber]; 00532 if (res != nil) 00533 return res; 00534 } 00535 return [CPDecimalNumber decimalNumberWithDecimal:result]; 00536 } 00537 00546 - (CPDecimalNumber)decimalNumberBySubtracting:(CPDecimalNumber)decimalNumber 00547 { 00548 return [self decimalNumberBySubtracting:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; 00549 } 00550 00560 - (CPDecimalNumber)decimalNumberBySubtracting:(CPDecimalNumber)decimalNumber withBehavior:(id <CPDecimalNumberBehaviors>)behavior 00561 { 00562 var result = CPDecimalMakeZero(), 00563 error = CPDecimalSubtract(result, [self decimalValue], [decimalNumber decimalValue], [behavior roundingMode]); 00564 00565 if (error > CPCalculationNoError) 00566 { 00567 var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber]; 00568 if (res != nil) 00569 return res; 00570 } 00571 return [CPDecimalNumber decimalNumberWithDecimal:result]; 00572 } 00573 00582 - (CPDecimalNumber)decimalNumberByDividingBy:(CPDecimalNumber)decimalNumber 00583 { 00584 return [self decimalNumberByDividingBy:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; 00585 } 00586 00596 - (CPDecimalNumber)decimalNumberByDividingBy:(CPDecimalNumber)decimalNumber withBehavior:(id <CPDecimalNumberBehaviors>)behavior 00597 { 00598 var result = CPDecimalMakeZero(), 00599 error = CPDecimalDivide(result, [self decimalValue], [decimalNumber decimalValue], [behavior roundingMode]); 00600 00601 if (error > CPCalculationNoError) 00602 { 00603 var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber]; 00604 if (res != nil) 00605 return res; 00606 } 00607 return [CPDecimalNumber decimalNumberWithDecimal:result]; 00608 } 00609 00618 - (CPDecimalNumber)decimalNumberByMultiplyingBy:(CPDecimalNumber)decimalNumber 00619 { 00620 return [self decimalNumberByMultiplyingBy:decimalNumber withBehavior:[CPDecimalNumber defaultBehavior]]; 00621 } 00622 00632 - (CPDecimalNumber)decimalNumberByMultiplyingBy:(CPDecimalNumber)decimalNumber withBehavior:(id <CPDecimalNumberBehaviors>)behavior 00633 { 00634 var result = CPDecimalMakeZero(), 00635 error = CPDecimalMultiply(result, [self decimalValue], [decimalNumber decimalValue], [behavior roundingMode]); 00636 00637 if (error > CPCalculationNoError) 00638 { 00639 var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:decimalNumber]; 00640 if (res != nil) 00641 return res; 00642 } 00643 return [CPDecimalNumber decimalNumberWithDecimal:result]; 00644 } 00645 00654 - (CPDecimalNumber)decimalNumberByMultiplyingByPowerOf10:(short)power 00655 { 00656 return [self decimalNumberByMultiplyingByPowerOf10:power withBehavior:[CPDecimalNumber defaultBehavior]]; 00657 } 00658 00668 - (CPDecimalNumber)decimalNumberByMultiplyingByPowerOf10:(short)power withBehavior:(id <CPDecimalNumberBehaviors>)behavior 00669 { 00670 var result = CPDecimalMakeZero(), 00671 error = CPDecimalMultiplyByPowerOf10(result, [self decimalValue], power, [behavior roundingMode]); 00672 00673 if (error > CPCalculationNoError) 00674 { 00675 var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:[CPDecimalNumber decimalNumberWithString:power.toString()]]; 00676 if (res != nil) 00677 return res; 00678 } 00679 return [CPDecimalNumber decimalNumberWithDecimal:result]; 00680 } 00681 00690 - (CPDecimalNumber)decimalNumberByRaisingToPower:(unsigned)power 00691 { 00692 return [self decimalNumberByRaisingToPower:power withBehavior:[CPDecimalNumber defaultBehavior]]; 00693 } 00694 00704 - (CPDecimalNumber)decimalNumberByRaisingToPower:(unsigned)power withBehavior:(id <CPDecimalNumberBehaviors>)behavior 00705 { 00706 if (power < 0) 00707 return [behavior exceptionDuringOperation:_cmd error:-1 leftOperand:self rightOperand:[CPDecimalNumber decimalNumberWithString:power.toString()]]; 00708 00709 var result = CPDecimalMakeZero(), 00710 error = CPDecimalPower(result, [self decimalValue], power, [behavior roundingMode]); 00711 00712 if (error > CPCalculationNoError) 00713 { 00714 var res = [behavior exceptionDuringOperation:_cmd error:error leftOperand:self rightOperand:[CPDecimalNumber decimalNumberWithString:power.toString()]]; 00715 if (res != nil) 00716 return res; 00717 } 00718 return [CPDecimalNumber decimalNumberWithDecimal:result]; 00719 } 00720 00728 - (CPDecimalNumber)decimalNumberByRoundingAccordingToBehavior:(id <CPDecimalNumberBehaviors>)behavior 00729 { 00730 var result = CPDecimalMakeZero(); 00731 00732 CPDecimalRound(result, [self decimalValue], [behavior scale], [behavior roundingMode]); 00733 00734 return [CPDecimalNumber decimalNumberWithDecimal:result]; 00735 } 00736 00744 - (CPComparisonResult)compare:(CPNumber)aNumber 00745 { 00746 // aNumber type is checked to convert if appropriate 00747 if (![aNumber isKindOfClass:[CPDecimalNumber class]]) 00748 aNumber = [CPDecimalNumber decimalNumberWithString:aNumber.toString()]; 00749 return CPDecimalCompare([self decimalValue], [aNumber decimalValue]); 00750 } 00751 00756 - (CPString)objCType 00757 { 00758 return @"d"; 00759 } 00760 00765 - (CPString)description 00766 { 00767 return [self descriptionWithLocale:nil] 00768 } 00769 00776 - (CPString)descriptionWithLocale:(CPDictionary)locale 00777 { 00778 return CPDecimalString(_data, locale); 00779 } 00780 00785 - (CPString)stringValue 00786 { 00787 return [self description]; 00788 } 00789 00795 - (CPDecimal)decimalValue 00796 { 00797 return CPDecimalCopy(_data); 00798 } 00799 00800 // Type Conversion Methods 00805 - (double)doubleValue 00806 { 00807 // FIXME: locale support / bounds check? 00808 return parseFloat([self stringValue]); 00809 } 00810 00815 - (BOOL)boolValue 00816 { 00817 return (CPDecimalIsZero(_data))?NO:YES; 00818 } 00819 00824 - (char)charValue 00825 { 00826 // FIXME: locale support / bounds check? 00827 return parseInt([self stringValue]); 00828 } 00829 00834 - (float)floatValue 00835 { 00836 // FIXME: locale support / bounds check? 00837 return parseFloat([self stringValue]); 00838 } 00839 00844 - (int)intValue 00845 { 00846 // FIXME: locale support / bounds check? 00847 return parseInt([self stringValue]); 00848 } 00849 00854 - (long long)longLongValue 00855 { 00856 // FIXME: locale support / bounds check? 00857 return parseInt([self stringValue]); 00858 } 00859 00864 - (long)longValue 00865 { 00866 // FIXME: locale support / bounds check? 00867 return parseInt([self stringValue]); 00868 } 00869 00874 - (short)shortValue 00875 { 00876 // FIXME: locale support / bounds check? 00877 return parseInt([self stringValue]); 00878 } 00879 00884 - (unsigned char)unsignedCharValue 00885 { 00886 // FIXME: locale support / bounds check? 00887 return parseInt([self stringValue]); 00888 } 00889 00894 - (unsigned int)unsignedIntValue 00895 { 00896 // FIXME: locale support / bounds check? 00897 return parseInt([self stringValue]); 00898 } 00899 00904 - (unsigned long)unsignedLongValue 00905 { 00906 // FIXME: locale support / bounds check? 00907 return parseInt([self stringValue]); 00908 } 00909 00914 - (unsigned short)unsignedShortValue 00915 { 00916 // FIXME: locale support / bounds check? 00917 return parseInt([self stringValue]); 00918 } 00919 00920 // CPNumber inherited methods 00927 - (BOOL)isEqualToNumber:(CPNumber)aNumber 00928 { 00929 return (CPDecimalCompare(CPDecimalMakeWithString(aNumber.toString(),nil), _data) == CPOrderedSame)?YES:NO; 00930 } 00931 00937 + (id)numberWithBool:(BOOL)aBoolean 00938 { 00939 return [[self alloc] initWithBool:aBoolean]; 00940 } 00941 00947 + (id)numberWithChar:(char)aChar 00948 { 00949 return [[self alloc] initWithChar:aChar]; 00950 } 00951 00957 + (id)numberWithDouble:(double)aDouble 00958 { 00959 return [[self alloc] initWithDouble:aDouble]; 00960 } 00961 00967 + (id)numberWithFloat:(float)aFloat 00968 { 00969 return [[self alloc] initWithFloat:aFloat]; 00970 } 00971 00977 + (id)numberWithInt:(int)anInt 00978 { 00979 return [[self alloc] initWithInt:anInt]; 00980 } 00981 00987 + (id)numberWithLong:(long)aLong 00988 { 00989 return [[self alloc] initWithLong:aLong]; 00990 } 00991 00997 + (id)numberWithLongLong:(long long)aLongLong 00998 { 00999 return [[self alloc] initWithLongLong:aLongLong]; 01000 } 01001 01007 + (id)numberWithShort:(short)aShort 01008 { 01009 return [[self alloc] initWithShort:aShort]; 01010 } 01011 01017 + (id)numberWithUnsignedChar:(unsigned char)aChar 01018 { 01019 return [[self alloc] initWithUnsignedChar:aChar]; 01020 } 01021 01027 + (id)numberWithUnsignedInt:(unsigned)anUnsignedInt 01028 { 01029 return [[self alloc] initWithUnsignedInt:anUnsignedInt]; 01030 } 01031 01037 + (id)numberWithUnsignedLong:(unsigned long)anUnsignedLong 01038 { 01039 return [[self alloc] initWithUnsignedLong:anUnsignedLong]; 01040 } 01041 01047 + (id)numberWithUnsignedLongLong:(unsigned long)anUnsignedLongLong 01048 { 01049 return [[self alloc] initWithUnsignedLongLong:anUnsignedLongLong]; 01050 } 01051 01057 + (id)numberWithUnsignedShort:(unsigned short)anUnsignedShort 01058 { 01059 return [[self alloc] initWithUnsignedShort:anUnsignedShort]; 01060 } 01061 01067 - (id)initWithBool:(BOOL)value 01068 { 01069 if (self = [self init]) 01070 _data = CPDecimalMakeWithParts((value)?1:0, 0); 01071 return self; 01072 } 01073 01079 - (id)initWithChar:(char)value 01080 { 01081 return [self _initWithJSNumber:value]; 01082 } 01083 01089 - (id)initWithDouble:(double)value 01090 { 01091 return [self _initWithJSNumber:value]; 01092 } 01093 01099 - (id)initWithFloat:(float)value 01100 { 01101 return [self _initWithJSNumber:value]; 01102 } 01103 01109 - (id)initWithInt:(int)value 01110 { 01111 return [self _initWithJSNumber:value]; 01112 } 01113 01119 - (id)initWithLong:(long)value 01120 { 01121 return [self _initWithJSNumber:value]; 01122 } 01123 01129 - (id)initWithLongLong:(long long)value 01130 { 01131 return [self _initWithJSNumber:value]; 01132 } 01133 01139 - (id)initWithShort:(short)value 01140 { 01141 return [self _initWithJSNumber:value]; 01142 } 01143 01149 - (id)initWithUnsignedChar:(unsigned char)value 01150 { 01151 return [self _initWithJSNumber:value]; 01152 } 01153 01159 - (id)initWithUnsignedInt:(unsigned)value 01160 { 01161 return [self _initWithJSNumber:value]; 01162 } 01163 01169 - (id)initWithUnsignedLong:(unsigned long)value 01170 { 01171 return [self _initWithJSNumber:value]; 01172 } 01173 01179 - (id)initWithUnsignedLongLong:(unsigned long long)value 01180 { 01181 return [self _initWithJSNumber:value]; 01182 } 01183 01189 - (id)initWithUnsignedShort:(unsigned short)value 01190 { 01191 return [self _initWithJSNumber:value]; 01192 } 01193 01194 - (id)_initWithJSNumber:value 01195 { 01196 if (self = [self init]) 01197 _data = CPDecimalMakeWithString(value.toString(), nil); 01198 return self; 01199 } 01200 01201 @end 01202 01203 // CPCoding category 01204 var CPDecimalNumberDecimalExponent = @"CPDecimalNumberDecimalExponent", 01205 CPDecimalNumberDecimalIsNegative = @"CPDecimalNumberDecimalIsNegative", 01206 CPDecimalNumberDecimalIsCompact = @"CPDecimalNumberDecimalIsCompact", 01207 CPDecimalNumberDecimalIsNaN = @"CPDecimalNumberDecimalIsNaN", 01208 CPDecimalNumberDecimalMantissa = @"CPDecimalNumberDecimalMantissa"; 01209 01210 @implementation CPDecimalNumber (CPCoding) 01211 01216 - (id)initWithCoder:(CPCoder)aCoder 01217 { 01218 if (self) 01219 { 01220 var dcm = CPDecimalMakeZero(); 01221 dcm._exponent = [aCoder decodeIntForKey:CPDecimalNumberDecimalExponent]; 01222 dcm._isNegative = [aCoder decodeBoolForKey:CPDecimalNumberDecimalIsNegative]; 01223 dcm._isCompact = [aCoder decodeBoolForKey:CPDecimalNumberDecimalIsCompact]; 01224 dcm._isNaN = [aCoder decodeBoolForKey:CPDecimalNumberDecimalIsNaN]; 01225 dcm._mantissa = [aCoder decodeObjectForKey:CPDecimalNumberDecimalMantissa]; 01226 [self initWithDecimal:dcm]; 01227 } 01228 01229 return self; 01230 } 01231 01236 - (void)encodeWithCoder:(CPCoder)aCoder 01237 { 01238 [aCoder encodeInt:_data._exponent forKey:CPDecimalNumberDecimalExponent]; 01239 [aCoder encodeBool:_data._isNegative forKey:CPDecimalNumberDecimalIsNegative]; 01240 [aCoder encodeBool:_data._isCompact forKey:CPDecimalNumberDecimalIsCompact]; 01241 [aCoder encodeBool:_data._isNaN forKey:CPDecimalNumberDecimalIsNaN]; 01242 [aCoder encodeObject:_data._mantissa forKey:CPDecimalNumberDecimalMantissa]; 01243 } 01244 01245 @end