iOS開發(fā) float類型不準(zhǔn)確

大家都會(huì)在開發(fā)中遇到, 處理一個(gè)浮點(diǎn)型的數(shù)據(jù)時(shí), 有時(shí)候會(huì)有一個(gè)精度的丟失, 造成數(shù)據(jù)不準(zhǔn)確. float的精度為6-7位有效數(shù)字,double的精度為15-16位,所以在處理浮點(diǎn)型數(shù)據(jù)時(shí)盡量選擇double類型。但是在一些涉及數(shù)據(jù)計(jì)算,大小比較時(shí)責(zé)任重大,非常容易出錯(cuò),因此使用系統(tǒng)自帶的NSDecimalNumber做處理, 能解決這問題。

1.NSDecimalNumber

NSDecimalNumber是NSNumber的不可變子類。蘋果針對(duì)浮點(diǎn)型計(jì)算時(shí)存在精度計(jì)算誤差的問題而提供的一個(gè)計(jì)算類,它是基于10進(jìn)制的定點(diǎn)計(jì)算保證了精度不會(huì)缺失。同時(shí)也可以定制精度的取正類型:向上取正、向下去正、四舍五入等。相對(duì)與浮點(diǎn)類型的計(jì)算,NSDecimalNumber提供了更加精準(zhǔn)的計(jì)算。

2.NSDecimalNumber 基本運(yùn)算
   //1、字符串 -> NSDecimalNumber
   NSDecimalNumber *num1 = [NSDecimalNumber decimalNumberWithString:@"123"];
   //2、NSNumber -> NSDecimalNumber(基礎(chǔ)類型的話,先轉(zhuǎn)成NSNumber)
   NSDecimalNumber *num2 = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInt:123] decimalValue]];
   //相關(guān)運(yùn)算
   /* +
   - (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;
   - (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;//帶保留小數(shù)位數(shù)
    */
   NSDecimalNumber *num3 = [num1 decimalNumberByAdding:num2];
   /*減 -
    - (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber;
    - (NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;//帶保留小數(shù)位數(shù)
    */
   NSDecimalNumber *num4 = [num1 decimalNumberBySubtracting:num2];
   /*乘 *
    - (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;
    - (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;//帶保留小數(shù)位數(shù)
    */
   NSDecimalNumber *num5 = [num1 decimalNumberByMultiplyingBy:num2];
   /*除 \
    - (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber;
    - (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;//帶保留小數(shù)位數(shù)
    */
   NSDecimalNumber *num6 = [num1 decimalNumberByDividingBy:num2];
   /*比較 
    - (NSComparisonResult)compare:(NSNumber *)decimalNumber;
    */
   NSComparisonResult result = [num1 compare:num2];
   NSLog(@"result == %ld",(long)result);
   //保留小數(shù)及相關(guān)參數(shù)含義
   /*保留小數(shù)
    + (instancetype)decimalNumberHandlerWithRoundingMode:(NSRoundingMode)roundingMode scale:(short)scale raiseOnExactness:(BOOL)exact raiseOnOverflow:(BOOL)overflow raiseOnUnderflow:(BOOL)underflow raiseOnDivideByZero:(BOOL)divideByZero;
    */
     // Rounding policies :
// 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  (特殊的四舍五入,碰到保留位數(shù)后一位的數(shù)字為5時(shí),根據(jù)前一位的奇偶性決定。為偶時(shí)向下取正,為奇數(shù)時(shí)向上取正。如:1.25保留1為小數(shù)。5之前是2偶數(shù)向下取正1.2;1.35保留1位小數(shù)時(shí)。5之前為3奇數(shù),向上取正1.4)


   typedef NS_ENUM(NSUInteger, NSRoundingMode) {
       NSRoundPlain,   // Round up on a tie
       NSRoundDown,    // Always down == truncate
       NSRoundUp,      // Always up
       NSRoundBankers  // on a tie round so last digit is even
   };
  //scale:保留有效小數(shù)的個(gè)數(shù)(為0的無效小數(shù)后自動(dòng)過濾).
  //Exactness:進(jìn)度異常、Overflow:向上溢出、Underflow:向下溢出、DivideByZero:除數(shù)為0。當(dāng)參數(shù)為YES出錯(cuò)會(huì)
  拋出異常,為NO時(shí)忽略異常。返回nil.
   NSDecimalNumberHandler *roundUp = [NSDecimalNumberHandler
                                      decimalNumberHandlerWithRoundingMode:NSRoundUp
                                      scale:2
                                      raiseOnExactness:NO
                                      raiseOnOverflow:NO
                                      raiseOnUnderflow:NO
                                      raiseOnDivideByZero:YES];

所以在處理有關(guān)浮點(diǎn)型數(shù)據(jù),后臺(tái)傳字符串的格式,防止丟失精度。

?著作權(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)容

  • 背景 在java中float賦值給double,會(huì)產(chǎn)生精度問題。 輸出為2.0999999046325684。 小...
    我叫小小強(qiáng)閱讀 19,523評(píng)論 2 23
  • 前言 在日常的開發(fā)中我們隨時(shí)都會(huì)跟數(shù)字打著交道,對(duì)數(shù)字的處理也是很平常的事,本文僅對(duì)常用的數(shù)字操作一個(gè)小結(jié),當(dāng)一個(gè)...
    進(jìn)無盡閱讀 1,403評(píng)論 0 2
  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,439評(píng)論 6 13
  • 你說, 秋天里, 泛黃的葉子,最美… 那時(shí), 我們總是牽拉著, 走上一段鋪滿葉子的小路… 踩在葉子上, 咯吱咯吱的...
    披覯閱讀 360評(píng)論 1 2
  • 我一次又一次地造訪 調(diào)緩匆忙的步履 想邂逅那位晚唐詩人 聽一詠三嘆的一瓢詩音 踏響古巷石板路的空寂 清雋的老人悠悠...
    錦茱萸閱讀 437評(píng)論 18 24

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