string轉(zhuǎn)數(shù)值出錯(cuò)

1.現(xiàn)象:

因APP業(yè)務(wù)需要,從后臺(tái)端取得軌跡點(diǎn)的string,包含一千及以上個(gè)經(jīng)緯度坐標(biāo)點(diǎn),數(shù)值精度為小數(shù)點(diǎn)后六位,string轉(zhuǎn)number類(lèi)型時(shí),精度仍然正確,又number轉(zhuǎn)double時(shí),精度出現(xiàn)變化,小數(shù)點(diǎn)第六位出現(xiàn)失真,例1.123456->1.123455999999或者1.123456000001這樣子。

2.解決辦法:

一開(kāi)始其實(shí)是用的float類(lèi)型,因?yàn)?位小數(shù)float類(lèi)型也足夠了,轉(zhuǎn)成double仍然沒(méi)解決問(wèn)題。查了下,由于double也就是浮點(diǎn)型類(lèi)型在計(jì)算機(jī)中的存在方式導(dǎo)致的此現(xiàn)象,無(wú)解。提工單給高德地圖,也無(wú)解,距離計(jì)算只接受double類(lèi)型,也沒(méi)有很好的辦法保證精度。

3.doble類(lèi)型不穩(wěn)定的解決辦法,(用于計(jì)算

1.與后臺(tái)等其他端的數(shù)據(jù)交互就用string格式;
2.本地?cái)?shù)據(jù)計(jì)算,非常精確的使用十進(jìn)制numberNSDecimalNumber格式來(lái)計(jì)算。

以下內(nèi)容來(lái)自引用原文鏈接
NSDecimalNumber類(lèi)型的的計(jì)算
NSDecimalNumber-十進(jìn)制數(shù),可以有小數(shù)點(diǎn),可以是正負(fù)數(shù)。繼承于NSNumber,常用于精確的數(shù)值計(jì)算,比如金融等方面。

  • + (NSDecimalNumber *)decimalNumberWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
    mantissa:長(zhǎng)整形;exponent:指數(shù);flag:正負(fù)數(shù)。
-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語(yǔ)言NSDecimal類(lèi)型轉(zhuǎn)成一個(gè)十進(jìn)制數(shù)。
  NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:1275 exponent:-2 isNegative:NO];   //12.75
  NSDecimal decimalValue = [subtotalAmount decimalValue];
  /**
   *  數(shù)據(jù)結(jié)構(gòu):
   (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;
    將字符串轉(zhuǎn)成一個(gè)十進(jìn)制數(shù)。
NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"-12.74"];      //-12.74
  discountAmount = [NSDecimalNumber decimalNumberWithString:@"127.4"];      //127.4
  • + (NSDecimalNumber *)decimalNumberWithString:(nullable NSString *)numberValue locale:(nullable id)locale;
    這個(gè)有點(diǎn)復(fù)雜,locale代表一種格式,就像date的格式化一樣。這里的locale可以傳遞兩種格式
    NSDictionary類(lèi)型:
NSDictionary *locale = [NSDictionary dictionaryWithObject:@"," forKey:NSLocaleDecimalSeparator];    //以","當(dāng)做小數(shù)點(diǎn)格式
NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"123,40" locale:locale];    //123.4
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"];    //法國(guó)數(shù)據(jù)格式,法國(guó)的小數(shù)點(diǎn)是','逗號(hào)
NSDecimalNumber *discountAmount = [NSDecimalNumber decimalNumberWithString:@"123,40" locale:locale];    //123.4
+(NSDecimalNumber *)zero; //0
+(NSDecimalNumber *)one; //1
+(NSDecimalNumber *)minimumDecimalNumber;
//-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+(NSDecimalNumber *)maximumDecimalNumber;
//3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+(NSDecimalNumber *)notANumber;
//非數(shù)字,常用于對(duì)比,比如:
[[NSDecimalNumber notANumber] isEqualToNumber:myNumber];
  • 加法運(yùn)算
-(NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;
-(NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 減法運(yùn)算
-(NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber;
-(NSDecimalNumber *)decimalNumberBySubtracting:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 乘法運(yùn)算
-(NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;
-(NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 除法運(yùn)算
-(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;
  • 指數(shù)運(yùn)算
-(NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power;
-(NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power 
withBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 四舍五入運(yùn)算
-(NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(nullable id <NSDecimalNumberBehaviors>)behavior;
  • 比較運(yùn)算
-(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對(duì)象都是不可變額,這意味著在它們創(chuàng)建之后不能改變它們的值
*還有這個(gè)博客可以參考下,比較全 *[關(guān)于OC中的小數(shù)精確計(jì)算---NSDecimalNumber]

4. 數(shù)據(jù)類(lèi)型的復(fù)習(xí)

既然都接觸到基本數(shù)據(jù)類(lèi)型了 ,順便回憶整理下基本數(shù)據(jù)類(lèi)型好了
OC的基本數(shù)據(jù)類(lèi)型包括:整型、字符型、浮點(diǎn)型、布爾型、枚舉型。

  • 一、整型
    整型包含以下幾種類(lèi)型
    1.short(短整型):內(nèi)存中通常占2字節(jié),即16位,取值范圍-32768 - +32767。
    2.int(整型):通常占4字節(jié),取值范圍-2147483648 - 2147483647
    3.long(長(zhǎng)整型):通常占8字節(jié)
    4.long long(長(zhǎng)整型):通常占8字節(jié)
    關(guān)于內(nèi)存中占用的字節(jié)數(shù),OC中并沒(méi)有硬性的規(guī)定,只是需要字節(jié)數(shù)符合以下條件:
    short <= int <= long<= long long
// 基本數(shù)據(jù)類(lèi)型  
int a = 10;  
//下面的數(shù)已經(jīng)超出了int的取值范圍,編譯器會(huì)提出警告  
int b = 10000000000000;  
NSLog(@"%d",b);  
//而這個(gè)數(shù)在long long的取值范圍內(nèi),所以不會(huì)溢出  
long long c =1000000000000;  
NSLog(@"%lld",c);  
//mac系統(tǒng)下輸出各種類(lèi)型占用的位數(shù)  
//輸出: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種進(jìn)制表示方式:十進(jìn)制,八進(jìn)制,十六進(jìn)制

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

整型前加上unsigned關(guān)鍵字后,將它變成無(wú)符號(hào)整型,最高位不是符號(hào)位,而是數(shù)值位。無(wú)符號(hào)整數(shù)不能表示負(fù)數(shù),但是表示范圍大了。

short s = 32768;  
unsigned short  us = 32768;  
//輸出-32768,32768,說(shuō)明正整數(shù)表示范圍比原先大了  
NSLog(@"%d,%u",s,us);  
  • 二、字符型
    字符型在OC中只占用一個(gè)字節(jié),OC字符變量不支持中文字符,字符需要使用’’包起來(lái),char類(lèi)型也可以看作整型值來(lái)使用,它是一個(gè)8位無(wú)符號(hào)整數(shù),取值范圍0-255。
    另外可以通過(guò)轉(zhuǎn)義字符表示特殊字符常量:
    | 轉(zhuǎn)義字符 | 說(shuō)明 |
    | --------- | ----- |
  • 三、浮點(diǎn)型
    浮點(diǎn)類(lèi)型包括float、double和long double,float占用4字節(jié),double占8字節(jié),long double占16字節(jié)。
    OC中浮點(diǎn)數(shù)表示方法有兩種,一種是包含小數(shù)點(diǎn)的簡(jiǎn)單的浮點(diǎn)數(shù),另一種是科學(xué)計(jì)數(shù)法形式的浮點(diǎn)數(shù)
//利用浮點(diǎn)數(shù)計(jì)算類(lèi)型取值范圍  
        int i0  =-1/0.0;  
        int i1 = 1/0.0;  
        //輸出:int型取值范圍:-2147483648-2147483647  
        NSLog(@"int型取值范圍:%d-%d",i0,i1);  
  • 四、布爾型
    OC中BOOL類(lèi)型有兩個(gè)值: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整數(shù)變量賦給BOOL類(lèi)型就一定得到Y(jié)ES,上面的768的出的就是NO,BOOL類(lèi)型實(shí)質(zhì)上就是signed char。
  • 五、枚舉型
    一個(gè)變量只有幾種可能的值,這個(gè)變量就可以定義為枚舉變量
enum season {spring,summer,fall,winter};  
enum season mySeason = spring;  
mySeason = summer;  
  • 六、格式字符
    在NSLog函數(shù)中我們使用了很多格式字符,如%d,%lu等。我們這里將介紹NSLog支持的格式字符。
    原文鏈接
  • 取值范圍
    為了以后開(kāi)發(fā)中能夠方便查找,并正確的使用數(shù)據(jù)類(lèi)型,下面是部分?jǐn)?shù)據(jù)類(lèi)型的取值范圍:
    int:-2147483648~2147483647
    unsigned int:0~4294967295
    short:-32768~32767
    unsigned short:0~65535
    long: -2147483648~2147483647
    unsigned long:0~4294967295
最后編輯于
?著作權(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)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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