iOS高精度數(shù)值計(jì)算

對(duì)于電商或者金融類app,使用float、double來(lái)計(jì)算價(jià)格數(shù)值可能是達(dá)不到要求的。使用apple官方API:NSDecimalNumber可能是更好的選擇。

  • 初始化

- (instancetype)initWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
- (instancetype)initWithDecimal:(NSDecimal)dcm;
- (instancetype)initWithString:(nullable NSString *)numberValue;
- (instancetype)initWithString:(nullable NSString *)numberValue locale:(nullable id)locale;


實(shí)例:
//mantissa:長(zhǎng)整形;exponent:指數(shù);flag:正負(fù)數(shù)          
NSDecimalNumber * amount0 = [[NSDecimalNumber alloc] initWithMantissa:42 exponent:-2 isNegative:NO];//0.42  
NSDecimalNumber * amount1 = [[NSDecimalNumber alloc] initWithMantissa:42 exponent:2 isNegative:NO];//-4200 

//locale代表一種格式,對(duì)于這種格式可以參考一下例子去理解  
NSDictionary *locale0 = [NSDictionary dictionaryWithObject:@"," forKey:NSLocaleDecimalSeparator];    //以","當(dāng)做小數(shù)點(diǎn)格式  
NSDecimalNumber * amount2 = [[NSDecimalNumber alloc] initWithString:@"42,68" locale:locale0];//42.68  
NSLocale *locale5 = [[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"];//法國(guó)數(shù)據(jù)格式,法國(guó)的小數(shù)點(diǎn)是','逗號(hào)  
NSDecimalNumber * amount3 = [[NSDecimalNumber alloc] initWithString:@"42.68" locale:locale5];//42.68  
  • 基本的算術(shù)方法
加法
- (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;
減法
- (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber;
乘法
- (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;
除法
- (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber;
冪次方
- (NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power;
指數(shù)
- (NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power;

  • 四舍五入運(yùn)算
- (NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;

+ (instancetype)decimalNumberHandlerWithRoundingMode:(NSRoundingMode)roundingMode scale:(short)scale raiseOnExactness:(BOOL)exact raiseOnOverflow:(BOOL)overflow raiseOnUnderflow:(BOOL)underflow raiseOnDivideByZero:(BOOL)divideByZero;


實(shí)例:
// 四舍五入策略 :
// Original
//    value 1.2  1.21  1.25  1.35  1.27
// Plain    1.2  1.2   1.3   1.4   1.3
// Down     1.2  1.2   1.2   1.3   1.2
// Up       1.2  1.3   1.3   1.4   1.3
// Bankers  1.2  1.2   1.2   1.4   1.3
roundingMode 要使用的舍入模式,有四種值: NSRoundUp, NSRoundDown, NSRoundPlain, and NSRoundBankers
scale 結(jié)果保留幾位小數(shù)
aiseOnExactness 發(fā)生精確錯(cuò)誤時(shí)是否拋出異常,一般為NO
raiseOnOverflow 發(fā)生溢出錯(cuò)誤時(shí)是否拋出異常,一般為NO
raiseOnUnderflow 發(fā)生不足錯(cuò)誤時(shí)是否拋出異常,一般為NO
raiseOnDivideByZero 被0除時(shí)是否拋出異常,一般為YES

NSDecimalNumberHandler * rounUp = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:1 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];  
NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:4284 exponent:-2 isNegative:NO];  
NSDecimalNumber * roundUpAmount = [subtotalAmount decimalNumberByRoundingAccordingToBehavior:rounUp]; 
  • 比較運(yùn)算

- (NSComparisonResult)compare:(NSNumber *)decimalNumber;

NSDecimalNumber *count0 = [NSDecimalNumber decimalNumberWithString:@"41"];  
NSDecimalNumber *count1 = [NSDecimalNumber decimalNumberWithString:@"43"];  
NSComparisonResult result = [count0 compare:count1]; 
// 上升 = NSOrderedAscending  1、2、3、。。。。。
if (result == NSOrderedAscending) {  
      //41 < 43  
} else if (result == NSOrderedSame) {  
      //41 == 43  
} else if (result == NSOrderedDescending) {  
      //41 > 43  
}  


參考
iOS開(kāi)發(fā)中高精度數(shù)值(貨幣)計(jì)算

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容