float陷阱

浮点数不准,这个貌似基本都知道。但是在开发中很多人没有对它的使用产生警觉。如果你在开发iOS应用,你可能使用过如下代码判断系统版本:


if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {  //something support for ios7 } 

这样一段代码也的确工作良好,但是注意了如果你把比较的数值改为7.1,那么很有可能就会出问题。

浮点数不准

这一篇博文从二进制的表示方面说明了为什么浮点数不准,讲的很好,感兴趣的可以学习学习,学习这些感觉还是很有用的,也可以帮助我们定位一些诡异的问题。

在精确的比较中不要使用float

文章开头的系统版本的比较就是一个典型的例子,我们可以通过其他方法实现比较:


if ([[[UIDevice currentDevice] systemVersion] compare:@"7.1"] != NSOrderedAscending) {  //something support for ios7 }
  1. NSString 两个字符串的比较,用 a compare:b 来比,得出的结果分3种
  2. 1. 26个字母比较  越靠后面  越大
  3. NSString *a = @"qweqwe";
  4. NSString *b = @"qweasd";
  5. BOOL result = [a compare:b];
  6. if (result == NSOrderedSame) {          // NSOrderedSame = 0 完全一样
  7. NSLog(@"a = b");
  8. }else if(result == NSOrderedAscending)  // NSOrderedAscending = -1
  9. NSLog(@"a < b");
  10. else{                                   //NSOrderedDescending = +1
  11. NSLog(@"a > b");
  12. }
  13. 2011-07-05 15:04:33.951 Q[5180:207] a > b
  14. 2.比较数字或者符号,或者字母 什么都行
  15. NSString *a = @"1.0.30qweqwe";
  16. NSString *b = @"1.0.45qweasd";
  17. BOOL result = [a compare:b];
  18. if (result == NSOrderedSame) {          // NSOrderedSame = 0 完全一样
  19. NSLog(@"a = b");
  20. }else if(result == NSOrderedAscending)  // NSOrderedAscending = -1
  21. NSLog(@"a < b");
  22. else{                                   //NSOrderedDescending = +1
  23. NSLog(@"a > b");
  24. }
  25. 2011-07-05 15:05:13.175 Q[5209:207] a < b
  26. 3.不考虑大小写比较字符串
  27. [a caseInsensitiveCompare:b]
  28. - (void)viewDidLoad
  29. {
  30. NSString *a = @"i love my boyfriend.";
  31. NSString *b = @"I Love My Boyfriend.";
  32. NSLog(@" \n a:  %@ \n",a);
  33. NSLog(@" \n b:  %@ \n",a);
  34. BOOL result = [a caseInsensitiveCompare:b] ==  NSOrderedSame;
  35. // result = (BOOL) YES;
  36. 4.不考虑大小写比较字符串
  37. [a caseInsensitiveCompare:b]
  38. - (void)viewDidLoad
  39. {
  40. NSString *a = @"i love my boyfriend.";
  41. NSString *b = @"Little baby.";
  42. NSLog(@" \n a:  %@ \n",a);
  43. NSLog(@" \n b:  %@ \n",a);
  44. BOOL result = [a caseInsensitiveCompare:b] ==  NSOrderedAscending;
  45. }
  46. //result = (BOOL) YES;
  47. 5. 有选择的比较大小   [a compare:b options:NSCaseInsensitiveSearch|NSNumericSearch]
  48. - (void)viewDidLoad
  49. {
  50. NSString *a = @"i love my boyfriend.";
  51. NSString *b = @"I Love My Boyfriend.";
  52. NSLog(@" \n a:  %@ \n",a);
  53. NSLog(@" \n b:  %@ \n",b);
  54. BOOL result = [a compare:b options:NSCaseInsensitiveSearch|NSNumericSearch] ==  NSOrderedSame;
  55. }
  56. //result = (BOOL)YES;
  57. NSCaseInsensitiveSearch  忽略大小写的比较字符串
  58. NSNumericSearch       比较字符串的个数
  59. NSLiteralSearch       区分大小写,进行完全比较
时间: 2024-11-05 19:04:20

float陷阱的相关文章

Java 浮点数 float或double类型的表示范围和精度

隐约记得,浮点数判断大小好像有陷阱,因为底层的二进制数不能精确表示所有的小数.有时候会产生让人觉得莫名其妙的事情. 如在java中, 0.99999999f==1f //true 0.9f==1f //false 要明白这些,首先要搞清楚float和double在内存结构 1.内存结构 float和double的范围是由指数的位数来决定的. float的指数位有8位,而double的指数位有11位,分布如下: float: 1bit(符号位) 8bits(指数位) 23bits(尾数位) dou

C++面试题6:sizeof 使用规则及陷阱

C++面试题6:sizeof 使用规则及陷阱 cout << sizeof(int) << endl; //32位机上int长度是4cout << sizeof(1==2) << endl; //bool类型,相当于cout << sizeof(bool) << endl;1 陷阱: int a=0; cout << sizeof(a=3) << endl; //sizeof作用范围内,也就是括号里面的内容不能

IO/ACM中来自浮点数的陷阱(收集向)

OI/ACM中经常要用到小数来解决问题(概率.计算几何等),但是小数在计算机中的存储方式是浮点数而不是我们在作数学运算中的数,有精度的限制. 以下以GUN C++为准,其他语言(或编译器)也差不了多少.本文竞赛向. 一.基础篇 1.一般浮点数使用double,范围为大概为-10^308 ~ 10^308,有效精度为15~16位10进制数. 2.一般没事(比如内存问题)不用float,而使用double,一个double占8个字节. 3.信息学竞赛一般使用scanf和printf输入输出,而浮点数

我的《C陷阱与缺陷》读书笔记

第一章 词法"陷阱" 1. =不同于== if(x = y) break; 实际上是将y赋给x,再检查x是否为0. 如果真的是这样预期,那么应该改为: if((x = y) != 0) break; 2. &和| 不同于 && 和 ||   3.词法分析中的"贪心法" 编译器将程序分解成符号的方法是:从左到有一个一个字符的读入,如果该字符可能组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符床是否可能是一个符号的组成部分:如

金融、支付行业的开发者不得不知道的float、double计算误差问题

在大多数行业涉及到浮点数的计算的场景比较少,但是在金融.支付行业就比较多了,而且在这两个行业一个小小的错误 可能将会给公司带来极大的损失. 以前我们公司就出现了这样的一个问题,当时使用的是double类型进行计算,导致计算出来的结果与实际的结果少了几十 元钱.虽然数额不大,但是引起产品.技术的重视.通过查阅相关资料,终于知道了是因为float.double在对含有小数的数值进行 计算过程中的舍入产生了误差. 在浮点运算中,浮点运算很少是精确的.虽然一些数字(譬如 0.5 )可以精确地表示为二进制

C/C++ 知识点---sizeof使用规则及陷阱分析

原文:http://blog.csdn.net/chenqi514/article/details/7245273 1.什么是sizeof 首先看一下sizeof在msdn上的定义:     The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value o

软件测试中LoadRunner函数中的几个陷阱

软件测试 中 LoadRunner 函数中的几个陷阱 1.atof 在 loadrunner 中如果直接用 float f; f=atof("123.00"); lr _output_message("%f",f); 输出的结果会是1244128.00,根本不是我们想要的. 因为float,double型在不同的平台下长度不一样,所以在loadrunner 软件测试中LoadRunner函数中的几个陷阱 1.atof 在loadrunner中如果直接用 float

C陷阱和缺陷整理四

1.assert宏的定义 #define assert(e) \ ((void)((e) || _assert_error(__FILE__, __LINE__))) 库里面对这个宏做了这样的定义,当宏参数(或表达式)e为真的时候由||运算符的运算规则会执行_assert_error(__FILE__, __LINE__)从而打印一条报警信息.所以整个表达式的最终会变为(void)0或者(void)1这种形式,这种形式确实有点奇怪? 系统这样定义的目的是当一个值被转换为void类型之后,没有一个

.NET陷阱之六:从枚举值持久化带来大量空间消耗谈起

好长时间没有写博文了,今天继续. 这次跟大家分享的内容起因于对一个枚举值列表的序列化,下面简化后的代码即能重现.为了明确起见,我显式指定了枚举的基础类型. // 定义一个枚举类型. public enum SomeEnum :int { First, Second, Third, ... ... } // 重现问题的代码. var list = new List<SomeEnum>(); for (int i = 0; i < 1000; ++i) { list.Add((SomeEnu