iOS 浮点数格式字符串比较大小 精度问题
2017-06-08 11:03
2071 查看
计算机中float的存储是不精确的。但是真正开发实践的时候,或许只有出问题了,才会醒悟:哦,原来是这样。这个问题在高大上的OC上同样存在,稍不注意就会出现问题。尤其是涉及金融的计算比较数据方面显得格外重要。
iOS开发中,请求后台的接口,然后转化为模型对象,最终转化为NSString对象,然后控件显示出来。这一切都是那么的自然那么的熟悉。但是如果服务器返回的时浮点数格式的字符串
并且客户端还要用到这个数据去做加减乘除 比较大小这类操作,十有八九会出错,如果再涉及金钱利润的时候 这个责任就会无限放大。那么怎样解决呢?下面就看一个例子。
从服务端请求回的数据clearrate字符串类型 需要乘以100再去和另外一个字段exper比较大小 正常的做法是:
CGFloat clearrate_float = [CUser.clearrate
floatValue]*100.0;
CGFloat per_assurescale_value = [model.per_assurescale_value floatValue];
if (clearrate_float > per_assurescale_value) {
}
这样看似没有问题,但是看一下真是数据就会发现有坑
真是返回数据是这样的:
{
code = 0;
data = {
clearrate = "1.05000000";
};
}
但是实际调试数据是这样的:
po clearrate_float
104.99999523162842
这样 返回的数据和自己转成浮点数在乘以100就会有误差! 那么接下来用到这个数据比较还是加减乘除都会出错!
*这事我们就要用到NSDecimalNumber这个类来处理浮点数的操作了
//100.0转化成NSDecimalNumber
NSDecimalNumber *decimalNumber_dit = [NSDecimalNumber
decimalNumberWithFloat:100.0];
//clearrate转化成NSDecimalNumber
NSDecimalNumber *decimalNumber_clearrate = [NSDecimalNumber
decimalNumberWithString:CUser.clearrate];
//两个数想乘
NSDecimalNumber *afterMultiplying_clearrate = [decimalNumber_clearrate
decimalNumberByMultiplyingBy:decimalNumber_dit];
//per_assurescale_value转化成NSDecimalNumber
NSDecimalNumber *decimalNumber_per_assurescale_value = [NSDecimalNumber
decimalNumberWithString:per_assurescale_value];
//最终两个浮点数比较大小变成NSDecimalNumber比较大小(如果有需求还可以加减乘除四则运算)
NSComparisonResult result_clearrate_float = [afterMultiplying_clearrate
compare:decimalNumber_per_assurescale_value];
//NSComparisonResult 的结果分为
NSOrderedAscending 升序
NSOrderedSame 相等
NSOrderedDescending 降序
这样再看一下实际调试po出来的数据:
po decimalNumber_clearrate
1.05
po afterMultiplying_clearrate
105
这样对NSDecimalNumber对象进行对比 四则运算都不会出错了。大家要切记浮点数运算要特别小心!
大家有什么建议 和 学习心得可以留言啊 欢迎大家共同进步
iOS开发中,请求后台的接口,然后转化为模型对象,最终转化为NSString对象,然后控件显示出来。这一切都是那么的自然那么的熟悉。但是如果服务器返回的时浮点数格式的字符串
并且客户端还要用到这个数据去做加减乘除 比较大小这类操作,十有八九会出错,如果再涉及金钱利润的时候 这个责任就会无限放大。那么怎样解决呢?下面就看一个例子。
从服务端请求回的数据clearrate字符串类型 需要乘以100再去和另外一个字段exper比较大小 正常的做法是:
CGFloat clearrate_float = [CUser.clearrate
floatValue]*100.0;
CGFloat per_assurescale_value = [model.per_assurescale_value floatValue];
if (clearrate_float > per_assurescale_value) {
}
这样看似没有问题,但是看一下真是数据就会发现有坑
真是返回数据是这样的:
{
code = 0;
data = {
clearrate = "1.05000000";
};
}
但是实际调试数据是这样的:
po clearrate_float
104.99999523162842
这样 返回的数据和自己转成浮点数在乘以100就会有误差! 那么接下来用到这个数据比较还是加减乘除都会出错!
*这事我们就要用到NSDecimalNumber这个类来处理浮点数的操作了
//100.0转化成NSDecimalNumber
NSDecimalNumber *decimalNumber_dit = [NSDecimalNumber
decimalNumberWithFloat:100.0];
//clearrate转化成NSDecimalNumber
NSDecimalNumber *decimalNumber_clearrate = [NSDecimalNumber
decimalNumberWithString:CUser.clearrate];
//两个数想乘
NSDecimalNumber *afterMultiplying_clearrate = [decimalNumber_clearrate
decimalNumberByMultiplyingBy:decimalNumber_dit];
//per_assurescale_value转化成NSDecimalNumber
NSDecimalNumber *decimalNumber_per_assurescale_value = [NSDecimalNumber
decimalNumberWithString:per_assurescale_value];
//最终两个浮点数比较大小变成NSDecimalNumber比较大小(如果有需求还可以加减乘除四则运算)
NSComparisonResult result_clearrate_float = [afterMultiplying_clearrate
compare:decimalNumber_per_assurescale_value];
//NSComparisonResult 的结果分为
NSOrderedAscending 升序
NSOrderedSame 相等
NSOrderedDescending 降序
这样再看一下实际调试po出来的数据:
po decimalNumber_clearrate
1.05
po afterMultiplying_clearrate
105
这样对NSDecimalNumber对象进行对比 四则运算都不会出错了。大家要切记浮点数运算要特别小心!
大家有什么建议 和 学习心得可以留言啊 欢迎大家共同进步
相关文章推荐
- iOS客户端学习-字符串比较大小
- 字符串转换成时间格式,并与本时区当前时间,比较大小。
- Java:日期字符串格式大小比较
- IOS将字符串转换为日期时间格式的一些问题
- iphone 移植时碰到到问题 二: 宽字符串 忽略 字符大小的比较 wcscasecmp wcsncasecmp
- JS中字符串比较大小判断的问题(转数字比较)
- 比较一个字符串日期和一个日期格式的日期的大小
- C++ 字符串转换为浮点数时的精度问题
- 在论坛中出现的比较难的sql问题:36(动态行转列 解析json格式字符串)
- 如何比较两个格式字符串的大小
- Java:日期字符串格式大小比较
- 解决js中字符串格式的时间比较问题
- 关于Sql Server中字符串比较大小写敏感的问题
- codeforces367(字符串hash求lcp比较大小,Trie解最大异或问题)
- Python中数字和字符串比较大小问题
- 转载: ios 比较两个日期格式(NSString,NSDate)的大小/前后 [复制链接]
- ios 比较两个日期格式(NSString,NSDate)的大小/前后
- javascript中的字符串数字比较大小的问题
- ios 比较两个日期格式(NSString,NSDate)的大小/前后
- hdu 2489 Minimal Ratio Tree DFS枚举点+最小生成树 属于中等偏上题 ,Double比较大小的时候注意精度问题