NSDecimalNumber 十進制數計算

由于使用Double計算經常會在小數點后精度問題和上取整、下取整、四舍五入方面出現問題,所以決定使用十進制數做金額、利率的計算。 NSDecimalNumber是NSNumber的子類。

一、初始化

//實例方法

-(instancetype)initWithMantissa:(unsignedlonglong)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
-(instancetype)initWithDecimal:(NSDecimal)dcm;
-(instancetype)initWithString:(nullableNSString *)numberValue;
-(instancetype)initWithString:(nullableNSString *)numberValue locale:(nullableid)locale;

//類方法

+(NSDecimalNumber *)decimalNumberWithMantissa:(unsignedlonglong)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
+(NSDecimalNumber *)decimalNumberWithDecimal:(NSDecimal)dcm;+ (NSDecimalNumber *)decimalNumberWithString:(nullableNSString *)numberValue;
+(NSDecimalNumber *)decimalNumberWithString:(nullableNSString *)numberValue locale:(nullableid)locale;

**e.g. **

NSDecimalNumber *subtotalAmount = [[NSDecimalNumber alloc]initWithString: @"12.34"]; //12.34
subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1234 exponent:-2 isNegative:NO];   //12.34 (
mantissa:長整形;exponent:指數;flag:正負數)
subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1234 exponent:2 isNegative:YES];   //-123400
discountAmount = [NSDecimalNumber decimalNumberWithString:@"123.4"];      //123.4

//NSDecimal類型
C語言NSDecimal類型和十進制數轉換

NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1234 exponent:-2 isNegative:NO];   //12.34
NSDecimal decimalValue = [subtotalAmount decimalValue];
subtotalAmount = [NSDecimalNumber decimalNumberWithDecimal:decimalValue];   //12.34

?//字符串轉換十進制數格式 : locale
locale代表一種格式,就像date的格式化一樣。這里的locale可以傳遞兩種格式

NSDictionary *locale = [NSDictionary dictionaryWithObject:@"," forKey:NSLocaleDecimalSeparator];    //以","當做小數點格式

NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"123,40" locale:locale];    //123.4
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"];    //法國數據格式,法國的小數點是','逗號

NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"123,40" locale:locale];    //123.4

二、加減乘除

加法運算

- (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;
- (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;

減法運算

- (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber;
- (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;

乘法運算

- (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;
- (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;

除法運算

- (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber;
- (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;

a的n次方

- (NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power;
- (NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;

指數運算

- (NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power;
- (NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power withBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;

四舍五入運算

- (NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(nullableid <NSDecimalNumberBehaviors>)behavior;

比較運算

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

e.g.

NSDecimalNumber *discount1 = [NSDecimalNumber decimalNumberWithString:@"1.2"];  
NSDecimalNumber *discount2 = [NSDecimalNumber decimalNumberWithString:@"1.3"];  
NSComparisonResult result = [discount1 compare:discount2];  
if (result == NSOrderedAscending) {
      NSLog(@"discount1 < discount2");
  } else if (result == NSOrderedSame) {
      NSLog(@"discount1 == discount2");
  } else if (result == NSOrderedDescending) {
      NSLog(@"discount1 > discount2");
  }

?三、格式化處理
NSDecimalNumberHandler

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

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

e.g.

NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler   decimalNumberHandlerWithRoundingMode:NSRoundBankers
                                       scale:2
                                       raiseOnExactness:NO
                                       raiseOnOverflow:NO
                                       raiseOnUnderflow:NO
                                       raiseOnDivideByZero:YES];
NSDecimalNumber *subtotal = [NSDecimalNumberdecimalNumberWithString:@"11.4035"];
NSDecimalNumber *discount = [NSDecimalNumberdecimalNumberWithString:@"3.22"];
NSDecimalNumber *total = [subtotal decimalNumberByAdding:discount withBehavior:roundUp];//14.62  兩個數相加然后舍去小數點后兩位以后的部分

枚舉

NSRoundPlain,   // Round up on a tie // 貌似是四舍五入
NSRoundDown,    // Always down == truncate  // 只舍不入
NSRoundUp,      // Always up   //  只入不舍
NSRoundBankers  // on a tie round so last digit is even  // 貌似是: if(四舍五入位 == 5)(四舍五入位(5)+  保留位 )%2 == 0 ? 入 : 舍;  if(四舍五入位 != 5) 遵從四舍五入

End、未補充
?NSDecimalNumberBehaviors
? NSDecimalNumberHandler
? NSRoundingMode

End、未驗證
所有NSDecimalNumber是不可變的,這意味著已經被創建后不能改變它們的值。

(本頁屬于摘抄備記筆記,集合網絡提供所需方法并加以補充驗證,由于來源過多并不一一列舉轉載地點,希望網絡可以流傳更精準更全面的技術筆記)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內容