iOS开发

OC浮点型精度问题

2017-01-16  本文已影响400人  南飞孤鸿

在OC中经常涉及到浮点型数据转换或者小数点后数据保留,这个就需要考虑到操作时浮点型数据精度问题。一般常用的有几种方法

一、不考虑四舍五入
1.直接类型转化
例如

float f = 1.5;
int a;
a = (int)f;
NSLog(@"a = %d",a); // 1

输出结果是1。(int)是强制类型转化,丢弃浮点数的小数部分。如果要保存小数点后多少为,就先乘再除

float f = 3.1415;
int b = f * 100;
float c = b/100.0;  
NSLog(@"b = %f",c); // 3.140000

2.使用NSDecimalNumber
NSDecimalNumber是NSNumber的子类,比NSNumber的功能更为强大,可以指定一个数的幂,四舍五入等操作。由于NSDecimalNumber精度较高,所以会比基本数据类型费时,所以需要权衡考虑,苹果官方建议在货币以及要求精度很高的场景下使用。

/**
 *  不四舍五入的将浮点型数据转成字符串
 *
 *  @param number   需要转换的浮点型数据
 *  @param position 保留小数点后几位
 */
-(NSString *)notRoundNumber:(double)number afterPoint:(int)position{
    
    NSDecimalNumberHandler* roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:position raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
    NSDecimalNumber *ouncesDecimal = [[NSDecimalNumber alloc] initWithFloat:price];
    NSDecimalNumber *roundedOunces = [ouncesDecimal decimalNumberByRoundingAccordingToBehavior:roundingBehavior];
    NSLog(@"%f", roundedOunces.floatValue);
    return [NSString stringWithFormat:@"%@",roundedOunces];
    
}

NSDecimalNumberHandler初始化时的关键参数:RoundingMode: 小数保留的类型
根据官方文档说明, 枚举值分析:
NSRoundPlain, 四舍五入
NSRoundDown, 只舍不入
NSRoundUp, 只入不舍
NSRoundBankers 四舍六入, 中间值时, 取最近的,保持保留最后一位为偶数

其他相关参数

参数 说明
scale 结果保留几位小数
raiseOnExactness 发生精确错误时是否抛出异常,一般为NO
raiseOnOverflow 发生溢出错误时是否抛出异常,一般为NO
raiseOnUnderflow 发生不足错误时是否抛出异常,一般为NO
raiseOnDivideByZero 被0除时是否抛出异常,一般为YES

参照一下图片, 理解上面枚举值:


RoundingMode.jpg

3.高斯函数,向下取整

float f = 1.6;
int a;
a = floor(f);
NSLog(@"a = %d",a); // 1

输出结果是1。floor()方法是向下取整,类似于数学中的高斯函数 .取得不大于浮点数的最大整数,对于正数来说是舍弃浮点数部分,对于负数来说,舍弃浮点数部分后再减1.

二、考虑四舍五入
1.使用round函数

round(12345.6789) 结果为:12346
round(12345.6789*100)/100 结果为:12345.68

2.通过强制类型转换
先将浮点型数据加上0.5,再进行转换

float f = 1.6;
int a;
a = (int)(f+0.5);
NSLog(@"a = %d",a); // 2

三、ceil函数,向上取整

float f = 1.5;
int a;
a = ceil(f);
NSLog(@"a = %d",a); // 2

ceil()方法是向上取整,取得不小于浮点数的最小整数,对于正数来说是舍弃浮点数部分并加1,对于负数来说就是舍弃浮点数部分.
精度转换时,经常要先乘以10的多少倍,之后再除以10的多少倍

上一篇下一篇

猜你喜欢

热点阅读