浮點(diǎn)數(shù)的轉(zhuǎn)化遇到的坑

非原創(chuàng)-搬運(yùn)記錄文章-浮點(diǎn)數(shù)的轉(zhuǎn)化遇到的坑

由于計(jì)算機(jī)表示小數(shù)(包括float和double型小數(shù))都有誤差强霎,我們不能直接用等號(==)判斷兩個(gè)小數(shù)是否相等召嘶。如何兩個(gè)小數(shù)的差的絕對值很小,比如小于 0.0000001陡舅,就可以認(rèn)為它們相等。

給出除了一個(gè)小數(shù)比較的方法:

bool (double num1, double num2) {
    if ((num1 - num2 > -0.0000001) && (num1 - num2) < 0.0000001)
        return true;
    else
        return false;
}

iOS Objective-c 中將NSString、NSNumber轉(zhuǎn)化成CGFloat會有精度丟失摆寄;
網(wǎng)絡(luò)傳輸中,JSON解析數(shù)字一般是NSNumber類型坯门,在轉(zhuǎn)化成CGFloat就會造成誤差微饥,網(wǎng)絡(luò)傳輸數(shù)字最好是轉(zhuǎn)成字符串類型。

OC小數(shù)轉(zhuǎn)化

在OC中是否也有這樣的問題古戴,于是乎我測試下欠橘,因?yàn)榭紤]到iOS開發(fā)時(shí),顯示的小數(shù)一般不會超過4位:

CGFloat a = 66.6;
CGFloat b = 66.66;
CGFloat c = 66.666;
CGFloat d = 66.6666;

// CGFloat 轉(zhuǎn)化成 NSNumber(一般會放進(jìn)NSArray, NSDictionary中)
NSNumber *an = [NSNumber numberWithFloat:a];
NSNumber *bn = [NSNumber numberWithFloat:b];
NSNumber *cn = [NSNumber numberWithFloat:c];
NSNumber *dn = [NSNumber numberWithFloat:d];

// NSNumber floatValue 轉(zhuǎn)化
float af = [an floatValue];
float bf = [bn floatValue];
float cf = [cn floatValue];
float df = [dn floatValue];

// NSNumber doubleValue 轉(zhuǎn)化
double ab = [an doubleValue];
double bb = [bn doubleValue];
double cb = [cn doubleValue];
double db = [dn doubleValue];

// CGFloat 轉(zhuǎn)化成 NSString
NSString *as = [NSString stringWithFormat:@"%f", a];
NSString *bs = [NSString stringWithFormat:@"%f", b];
NSString *cs = [NSString stringWithFormat:@"%f", c];
NSString *ds = [NSString stringWithFormat:@"%f", d];

// NSString floatValue 轉(zhuǎn)化
float asf =[as floatValue];
float bsf =[bs floatValue];
float csf =[cs floatValue];
float dsf =[ds floatValue];

// NSString doubleValue 轉(zhuǎn)化
double asb = [as doubleValue];
double bsb = [bs doubleValue];
double csb = [cs doubleValue];
double dsb = [ds doubleValue];

打印信息:

== CGFloat 打印
a: 66.600000
b: 66.660000
c: 66.666000
d: 66.666600

== NSNumber 打印
an: 66.6
bn: 66.66
cn: 66.666
dn: 66.6666

== NSNumber floatValue 打印
af: 66.599998
bf: 66.660004
cf: 66.666000
df: 66.666603

== NSNumber doubleValue 打印
ab: 66.599998
bb: 66.660004
cb: 66.666000
db: 66.666603

== NSString 打印
as: 66.600000
bs: 66.660000
cs: 66.666000
ds: 66.666600

== NSString floatValue 打印
asf: 66.599998
bsf: 66.660004
csf: 66.666000
dsf: 66.666603

== NSString doubleValue 打印
asb: 66.600000
bsb: 66.660000
csb: 66.666000
dsb: 66.666600

NSString doubleValue 轉(zhuǎn)化下來的小數(shù)是比較準(zhǔn)確的现恼。

JSON小數(shù)轉(zhuǎn)化

App應(yīng)用一般數(shù)據(jù)都是從接口傳來的

測一測JSON傳數(shù)字:

NSString *json = @"{"a":66.6, "b":66.66, "c":66.666, "d":66.6666}";
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"%@", dict);
for (NSString *key in [dict allKeys]) {
 id object = [dict objectForKey:key];
 NSLog(@"%@: %@ - %@", key, [object class], object);

 float xf = [object floatValue];
 double yf = [object doubleValue];
 printf("nf: %f - df: %fn", xf, yf);
}

打印信息:

{
 a = "66.59999999999999";
 b = "66.66";
 c = "66.666";
 d = "66.6666";
}
d: __NSCFNumber - 66.6666
nf: 66.666603 - df: 66.666600

b: __NSCFNumber - 66.66
nf: 66.660004 - df: 66.660000

c: __NSCFNumber - 66.666
nf: 66.666000 - df: 66.666000

a: __NSCFNumber - 66.59999999999999
nf: 66.599998 - df: 66.600000

JSON傳字符串:

NSString *json = @"{"a":"66.6","b":"66.66","c":"66.666","d":"66.6666"}";
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"dict: %@", dict);
for (NSString *key in [dict allKeys]) {
 id object = [dict objectForKey:key];
 NSLog(@"%@: %@ - %@", key, [object class], object);

 float xf = [object floatValue];
 double yf = [object doubleValue];
 printf("nf: %f - df: %fn", xf, yf);
}

輸出信息:

{
 a = "66.6";
 b = "66.66";
 c = "66.666";
 d = "66.6666";
}
d: NSTaggedPointerString - 66.6666
nf: 66.666603 - df: 66.666600

b: NSTaggedPointerString - 66.66
nf: 66.660004 - df: 66.660000

c: NSTaggedPointerString - 66.666
nf: 66.666000 - df: 66.666000

a: NSTaggedPointerString - 66.6
nf: 66.599998 - df: 66.600000

最后

聰明的你應(yīng)該看出:

  1. NSNumber NSString 盡量用 doubleValue 來轉(zhuǎn)化肃续, 千萬不能用 floatValue黍檩。
  2. 勸后臺的同事把請求返回的數(shù)據(jù)全部設(shè)置為 String 類型。
  3. 如果涉及到精確計(jì)算的問題始锚,請用 NSDecimalNumber 對象了參考刽酱。

參考
iOS浮點(diǎn)數(shù)的轉(zhuǎn)化遇到的坑
iOS開發(fā)可能遇到的坑——浮點(diǎn)數(shù)的轉(zhuǎn)化顯示問題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瞧捌,隨后出現(xiàn)的幾起案子棵里,更是在濱河造成了極大的恐慌,老刑警劉巖姐呐,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件殿怜,死亡現(xiàn)場離奇詭異,居然都是意外死亡曙砂,警方通過查閱死者的電腦和手機(jī)稳捆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麦轰,“玉大人乔夯,你說我怎么就攤上這事】钋郑” “怎么了末荐?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長新锈。 經(jīng)常有香客問我甲脏,道長,這世上最難降的妖魔是什么妹笆? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任块请,我火速辦了婚禮,結(jié)果婚禮上拳缠,老公的妹妹穿的比我還像新娘墩新。我一直安慰自己,他們只是感情好窟坐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布海渊。 她就那樣靜靜地躺著,像睡著了一般哲鸳。 火紅的嫁衣襯著肌膚如雪臣疑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天徙菠,我揣著相機(jī)與錄音讯沈,去河邊找鬼。 笑死婿奔,一個(gè)胖子當(dāng)著我的面吹牛缺狠,可吹牛的內(nèi)容都是我干的问慎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼儒老,長吁一口氣:“原來是場噩夢啊……” “哼蝴乔!你這毒婦竟也來了记餐?” 一聲冷哼從身側(cè)響起驮樊,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎片酝,沒想到半個(gè)月后囚衔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡雕沿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年练湿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片审轮。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肥哎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出疾渣,到底是詐尸還是另有隱情篡诽,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布榴捡,位于F島的核電站杈女,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏吊圾。R本人自食惡果不足惜达椰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望项乒。 院中可真熱鬧啰劲,春花似錦、人聲如沸檀何。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽埃碱。三九已至猖辫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間砚殿,已是汗流浹背啃憎。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留似炎,地道東北人辛萍。 一個(gè)月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓悯姊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贩毕。 傳聞我的和親對象是個(gè)殘疾皇子悯许,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容