在此之前先回顾一下小知识点:
CGFloat为double或float的typedef
NSInteger为long或int的typedef
NSUInteger为unsigned long或unsigned int的typedef
typedef float CGFloat; // 32-bit
typedef double CGFloat; // 64-bit
typedef int NSInteger; // 32-bit
typedef long NSInteger; // 64-bit
typedef unsigned int NSUInteger; // 32-bit
typedef unsigned long NSUInteger; // 64-bit
extern float ceilf(float);
extern double ceil(double);
extern long double ceill(long double);
extern float floorf(float);
extern double floor(double);
extern long double floorl(longdouble);
extern float roundf(float);
extern double round(double);
extern long double roundl(long double);
round 如果参数是小数 则求本身的四舍五入.
ceil 如果参数是小数 则求最小的整数但不小于本身.
floor 如果参数是小数 则求最大的整数但不大于本身.
Example:
round(3.4) --- 3 ceil(3.4) --- 4 floor(3.4) --- 3
round(3.5) --- 4 ceil(3.5) --- 4 floor(3.5) --- 3
CGFloat tempNum = 5.234;
tempNum *= 100;
NSLog(@"%.2f", ceil(tempNum)/100); //打印的为5.24
杜撰一下所使用的场景: iOS客户端计算出来的手续费5.24333或者5.246666等五花八门的金额.此时,我们收取的金额(肯定要保留小数点后两位)应该是无穷进这个概念. 就会用到上面的 ceil 函数.
在此推荐一个苹果针对浮点型计算时存在精度计算误差的问题而提供的一个计算类 NSDecimalNumber
NSDecimalNumber是NSNumber的不可变子类, 它是基于十进制的定点计算保证了精度不会缺失。同时也可以定制精度的取正类型:向上取正、向下去正、四舍五入等。相对与浮点类型的计算,NSDecimalNumber提供了更加精准的计算。
/**
客户端手续费计算方法并解决金额精度问题
@param amountValue 用户输入的具体金额
@param rateValue 后台给予的费率
@return 客户端计算出的手续费
*/
-(NSString *)tt_ClientFeeCalculationMethodWithString:(NSString *)amountValue with:(NSString *)rateValue{
/*手续费计算精度问题解决:NSDecimalNumber
加: decimalNumberByAdding
减: decimalNumberBySubtracting:
乘: decimalNumberByMultiplyingBy:
除: decimalNumberByDividingBy:
*/
rateValue = [NSString stringWithFormat:@"%@%%",rateValue];
NSDecimalNumber *rateValueNumber = [NSDecimalNumber decimalNumberWithString:rateValue];
NSDecimalNumber *oneHundredValueNumber = [NSDecimalNumber decimalNumberWithString:[NSString stringWithFormat:@"%d", 100]];
NSDecimalNumber *division = [rateValueNumber decimalNumberByDividingBy:oneHundredValueNumber];
NSDecimalNumber *amountValueNumber = [NSDecimalNumber decimalNumberWithString:amountValue];
NSDecimalNumber *product = [amountValueNumber decimalNumberByMultiplyingBy:division];
NSLog(@"%@", [product stringValue]);
/*四舍五入精确度问题解决:NSDecimalNumberHandler
讲述下参数的含义:
RoundingMode: 简单讲就是你要四舍五入操作的标准.
scale : 需要保留的精度。
raiseOnExactness : 为YES时在处理精确时如果有错误,就会抛出异常。
raiseOnOverflow : YES时在计算精度向上溢出时会抛出异常,否则返回。
raiseOnUnderflow : YES时在计算精度向下溢出时会抛出异常,否则返回.
raiseOnDivideByZero : YES时。当除以0时会抛出异常,否则返回。
*/
NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundUp
scale:2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO];
NSString *tempStr =[[product decimalNumberByRoundingAccordingToBehavior:roundingBehavior] stringValue];
NSLog(@"%@",tempStr);
return tempStr;
}
网友评论