在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 |
参照一下图片, 理解上面枚举值:
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的多少倍