iOS 數(shù)字精準(zhǔn)計(jì)算之NSDecimalNumber


NSDecimalNumber簡(jiǎn)介

顧名思義這是一個(gè)十進(jìn)制數(shù)字類,繼承自NSNumber,蘋果針對(duì)浮點(diǎn)類型計(jì)算精度問題提供出來的計(jì)算類,基于十進(jìn)制的科學(xué)計(jì)數(shù)法來計(jì)算,同時(shí)可以指定舍入模式,一般用于貨幣計(jì)算。

初始化方法
/**
 創(chuàng)建并返回一個(gè)十進(jìn)制對(duì)象
 @param dcm 十進(jìn)制的結(jié)構(gòu)體
 */
- (instancetype)initWithDecimal:(NSDecimal)dcm;

/**
 @param mantissa 十進(jìn)制尾數(shù) (如:123)
 @param exponent 指數(shù)      (如:3)
 @param flag 是否為負(fù)      (如:YES)
 return 十進(jìn)制數(shù)字對(duì)象       (如:-123000)
 */
- (instancetype)initWithMantissa:(unsigned long long)mantissa
                        exponent:(short)exponent
                      isNegative:(BOOL)flag;

/**
 @param numberValue 數(shù)字字符串
 */
- (instancetype)initWithString:(nullable NSString *)numberValue;

/**
 @param numberValue 數(shù)字字符串,可以根據(jù)locale來解析 (如:@"123,456")
 @param locale 解析<numberValue>的字典(特別是NSLocaleDecimalSeparator:分割整數(shù)跟小數(shù))
                                                (如 @{NSLocaleDecimalSeparator:@","})
 @return 十進(jìn)制數(shù)字對(duì)象                           (如:123.456)
 */
- (instancetype)initWithString:(nullable NSString *)numberValue
                        locale:(nullable id)locale;

NSDecimalNumberHandler

這是一個(gè)NSDecimalNumber的公共協(xié)議處理類,可以設(shè)置舍入模式以及計(jì)算錯(cuò)誤的處理;配合NSDecimalNumber來使用,將這個(gè)類的實(shí)例當(dāng)做NSDecimalNumber相應(yīng)API的參數(shù)來控制數(shù)字處理的結(jié)果。

/**
 初始化方法

 @param roundingMode 舍入方式
 @param scale 小數(shù)點(diǎn)后舍入值的位數(shù)。
 @param exact 精度錯(cuò)誤處理;YES:如果出現(xiàn)錯(cuò)誤,將引發(fā)異常,NO:忽略錯(cuò)誤并將控制權(quán)放回給調(diào)用者。
 @param overflow 溢出錯(cuò)誤處理;YES:如果出現(xiàn)錯(cuò)誤,將引發(fā)異常,NO:忽略錯(cuò)誤并將控制權(quán)放回給調(diào)用者。
 @param underflow 下溢錯(cuò)誤處理;YES:如果出現(xiàn)錯(cuò)誤,將引發(fā)異常,NO:忽略錯(cuò)誤并將控制權(quán)放回給調(diào)用者。
 @param divideByZero 除以0的錯(cuò)誤處理;YES:如果出現(xiàn)錯(cuò)誤,將引發(fā)異常,NO:忽略錯(cuò)誤并將控制權(quán)放回給調(diào)用者。
 @return NSDecimalNumberHandler對(duì)象
 */
+ (instancetype)decimalNumberHandlerWithRoundingMode:(NSRoundingMode)roundingMode
                                               scale:(short)scale
                                    raiseOnExactness:(BOOL)exact
                                     raiseOnOverflow:(BOOL)overflow
                                    raiseOnUnderflow:(BOOL)underflow
                                 raiseOnDivideByZero:(BOOL)divideByZero

/**
 快速構(gòu)造方法

 roundingMode:NSRoundPlain
 scale:全精度
 exact:NO
 overflow:NO
 underflow:NO
 divideByZero:NO
 */
+ (NSDecimalNumberHandler *)defaultDecimalNumberHandler;

NSRoundingMode的幾種方式:

  • NSRoundPlain:四舍五入
  • NSRoundDown:只舍不入
  • NSRoundUp:只入不舍
  • NSRoundBankers: 在四舍五入的基礎(chǔ)上加了一個(gè)判斷:當(dāng)最后一位為5的時(shí)候,只會(huì)舍入成偶數(shù)。比如:1.25不會(huì)返回1.3而是1.2,因?yàn)?.3不是偶數(shù)。
官方文檔提供的圖片

加法運(yùn)算
/**
 @param decimalNumber 相加的十進(jìn)制對(duì)象
 */
- (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;

/**
 @param decimalNumber 相加的十進(jìn)制對(duì)象
 @param behavior NSDecimalNumberHandler對(duì)象
 */
- (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber
                              withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior
減法運(yùn)算
/**
 @param decimalNumber 減去的十進(jìn)制對(duì)象
 */
- (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber;

/**
 @param decimalNumber 減去的十進(jìn)制對(duì)象
 @param behavior NSDecimalNumberHandler對(duì)象
 */
- (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber
                                   withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
乘法運(yùn)算
/**
 @param decimalNumber 相乘的十進(jìn)制對(duì)象
 */
- (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;

/**
 @param decimalNumber 相乘的十進(jìn)制對(duì)象
 @param behavior NSDecimalNumberHandler對(duì)象
 */
- (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber
                                     withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
除法運(yùn)算
/**
 @param decimalNumber 除以的十進(jìn)制對(duì)象
 */
- (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber;

/**
 @param decimalNumber  除以的十進(jìn)制對(duì)象
 @param behavior NSDecimalNumberHandler對(duì)象
 */
- (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber
                                  withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
次方運(yùn)算
/**
 @param power 指數(shù)
 return 調(diào)用者的power次方
 */
- (NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power;

/**
 @param power 指數(shù)
 @param behavior NSDecimalNumberHandler對(duì)象
 return 調(diào)用者的power次方
 */
- (NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power
                                      withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
10為底的乘方運(yùn)算
/**
 調(diào)用者乘以10的power次方

 @param power 10的指數(shù)
 */
- (NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power;

/**
 調(diào)用者乘以10的power次方

 @param power 10的指數(shù)
 @param behavior NSDecimalNumberHandler對(duì)象
 */
- (NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power
                                              withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
舍入運(yùn)算
/**
 @param decimalNumber NSDecimalNumberHandler對(duì)象
 */
- (NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;

總結(jié)

之前被這個(gè)NSRoundingMode狠狠的坑了一把,把NSRoundBankers當(dāng)做四舍五入,最后運(yùn)算出來的結(jié)果有時(shí)跟后臺(tái)差0.1,查了好久,最后在蘋果官方文檔上才發(fā)現(xiàn)模式用錯(cuò)了??。所以在這里我主要把一系列的API跟參數(shù)進(jìn)行解釋,方便大家去理解運(yùn)用。

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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