计算机中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对象进行对比 四则运算都不会出错了。大家要切记浮点数运算要特别小心!