string轉數值出錯

1.現象:

因APP業務需要,從后臺端取得軌跡點的string,包含一千及以上個經緯度坐標點,數值精度為小數點后六位,string轉number類型時,精度仍然正確,又number轉double時,精度出現變化,小數點第六位出現失真,例1.123456->1.123455999999或者1.123456000001這樣子。

2.解決辦法:

一開始其實是用的float類型,因為6位小數float類型也足夠了,轉成double仍然沒解決問題。查了下,由于double也就是浮點型類型在計算機中的存在方式導致的此現象,無解。提工單給高德地圖,也無解,距離計算只接受double類型,也沒有很好的辦法保證精度。

3.doble類型不穩定的解決辦法,(用于計算

1.與后臺等其他端的數據交互就用string格式;
2.本地數據計算,非常精確的使用十進制numberNSDecimalNumber格式來計算。

以下內容來自引用原文鏈接
NSDecimalNumber類型的的計算
NSDecimalNumber-十進制數,可以有小數點,可以是正負數。繼承于NSNumber,常用于精確的數值計算,比如金融等方面。

  • + (NSDecimalNumber *)decimalNumberWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
    mantissa:長整形;exponent:指數;flag:正負數。
-NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1275 exponent:-2 isNegative:NO];   //12.75
subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1275 exponent:2 isNegative:YES];   //-127500
  • + (NSDecimalNumber *)decimalNumberWithDecimal:(NSDecimal)dcm;
    將C語言NSDecimal類型轉成一個十進制數。
  NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1275 exponent:-2 isNegative:NO];   //12.75
  NSDecimal decimalValue = [subtotalAmount decimalValue];
  /**
   *  數據結構:
   (NSDecimal) decimalValue = {
   _exponent = -2
   _length = 1
   _isNegative = 0
   _isCompact = 1
   _reserved = 0
   _mantissa = ([0] = 1275, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0, [7] = 0)
   */
  subtotalAmount = [NSDecimalNumber decimalNumberWithDecimal:decimalValue];   //12.75
  • + (NSDecimalNumber *)decimalNumberWithString:(nullable NSString *)numberValue;
    將字符串轉成一個十進制數。
NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"-12.74"];      //-12.74
  discountAmount = [NSDecimalNumber decimalNumberWithString:@"127.4"];      //127.4
  • + (NSDecimalNumber *)decimalNumberWithString:(nullable NSString *)numberValue locale:(nullable id)locale;
    這個有點復雜,locale代表一種格式,就像date的格式化一樣。這里的locale可以傳遞兩種格式
    NSDictionary類型:
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 *)zero; //0
+(NSDecimalNumber *)one; //1
+(NSDecimalNumber *)minimumDecimalNumber;
//-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+(NSDecimalNumber *)maximumDecimalNumber;
//3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+(NSDecimalNumber *)notANumber;
//非數字,常用于對比,比如:
[[NSDecimalNumber notANumber] isEqualToNumber:myNumber];
  • 加法運算
-(NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;
-(NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 減法運算
-(NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber;
-(NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 乘法運算
-(NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;
-(NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 除法運算
-(NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber;
-(NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • a的n次方
-(NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power;
-(NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 指數運算
-(NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power;
-(NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power 
withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 四舍五入運算
-(NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 比較運算
-(NSComparisonResult)compare:(NSNumber *)decimalNumber;

示例

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

注意:像NSNumber一樣,所有的NSDecimalNumber對象都是不可變額,這意味著在它們創建之后不能改變它們的值
*還有這個博客可以參考下,比較全 *[關于OC中的小數精確計算---NSDecimalNumber]

4. 數據類型的復習

既然都接觸到基本數據類型了 ,順便回憶整理下基本數據類型好了
OC的基本數據類型包括:整型、字符型、浮點型、布爾型、枚舉型。

  • 一、整型
    整型包含以下幾種類型
    1.short(短整型):內存中通常占2字節,即16位,取值范圍-32768 - +32767。
    2.int(整型):通常占4字節,取值范圍-2147483648 - 2147483647
    3.long(長整型):通常占8字節
    4.long long(長整型):通常占8字節
    關于內存中占用的字節數,OC中并沒有硬性的規定,只是需要字節數符合以下條件:
    short <= int <= long<= long long
// 基本數據類型  
int a = 10;  
//下面的數已經超出了int的取值范圍,編譯器會提出警告  
int b = 10000000000000;  
NSLog(@"%d",b);  
//而這個數在long long的取值范圍內,所以不會溢出  
long long c =1000000000000;  
NSLog(@"%lld",c);  
//mac系統下輸出各種類型占用的位數  
//輸出:short:2 int:4  long:8  long long:8  
NSLog(@"short:%lu int:%lu  long:%lu  long long:%lu",sizeof(short),sizeof(int),sizeof(long),sizeof(long long));

整型有3種進制表示方式:十進制,八進制,十六進制

//八進制,以0開頭  
     int i8 = 010;  
     //十進制  
     int i10 = 10;  
     //十六進制,以0x或者0X開頭  
     int i16 = 0x10;  
     //8  10   16  
     NSLog(@"%d  %d   %d",i8,i10,i16);  

整型前加上unsigned關鍵字后,將它變成無符號整型,最高位不是符號位,而是數值位。無符號整數不能表示負數,但是表示范圍大了。

short s = 32768;  
unsigned short  us = 32768;  
//輸出-32768,32768,說明正整數表示范圍比原先大了  
NSLog(@"%d,%u",s,us);  
  • 二、字符型
    字符型在OC中只占用一個字節,OC字符變量不支持中文字符,字符需要使用’’包起來,char類型也可以看作整型值來使用,它是一個8位無符號整數,取值范圍0-255。
    另外可以通過轉義字符表示特殊字符常量:
    | 轉義字符 | 說明 |
    | --------- | ----- |
  • 三、浮點型
    浮點類型包括float、double和long double,float占用4字節,double占8字節,long double占16字節。
    OC中浮點數表示方法有兩種,一種是包含小數點的簡單的浮點數,另一種是科學計數法形式的浮點數
//利用浮點數計算類型取值范圍  
        int i0  =-1/0.0;  
        int i1 = 1/0.0;  
        //輸出:int型取值范圍:-2147483648-2147483647  
        NSLog(@"int型取值范圍:%d-%d",i0,i1);  
  • 四、布爾型
    OC中BOOL類型有兩個值:YES和NO
BOOL b1 = YES;  
if (b1) {  
    NSLog(@"%d",b1);  
}  
BOOL b1 = 10;  
//輸出: YES: 10  
if (b1) {  
    NSLog(@"YES: %d",b1);  
}else{  
    NSLog(@"NO: %d",b1);  
}  
BOOL b1 = 768;  
//輸出: NO: 0  
if (b1) {  
    NSLog(@"YES: %d",b1);  
}else{  
    NSLog(@"NO: %d",b1);  
}  
//注意:不要以為所有的非0整數變量賦給BOOL類型就一定得到YES,上面的768的出的就是NO,BOOL類型實質上就是signed char。
  • 五、枚舉型
    一個變量只有幾種可能的值,這個變量就可以定義為枚舉變量
enum season {spring,summer,fall,winter};  
enum season mySeason = spring;  
mySeason = summer;  
  • 六、格式字符
    在NSLog函數中我們使用了很多格式字符,如%d,%lu等。我們這里將介紹NSLog支持的格式字符。
    原文鏈接
  • 取值范圍
    為了以后開發中能夠方便查找,并正確的使用數據類型,下面是部分數據類型的取值范圍:
    int:-2147483648~2147483647
    unsigned int:0~4294967295
    short:-32768~32767
    unsigned short:0~65535
    long: -2147483648~2147483647
    unsigned long:0~4294967295
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,936評論 6 535
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,744評論 3 421
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,879評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,181評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,935評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,325評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,384評論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,534評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,084評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,892評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,067評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,623評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,322評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,735評論 0 27
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,990評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,800評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,084評論 2 375

推薦閱讀更多精彩內容