在iOS开发中,遇到和货币价格计算相关的,对计算精度要求比较高。使用float类型运算,经常出现误差。为了解决这种问题我们使用NSDecimalNumber。
一、基本算法
1、字符串初始化为NSDecimalNumber
NSDecimalNumber *number1 = [NSDecimalNumber decimalNumberWithString:@"123"];
NSDecimalNumber *number2 = [NSDecimalNumber decimalNumberWithString:@"6.12"];
2、加法运算
NSDecimalNumber *num = [number2 decimalNumberByAdding:number1];
3、减法运算
NSDecimalNumber *num = [number1 decimalNumberBySubtracting:number2];
4、乘法运算
NSDecimalNumber *num = [number1 decimalNumberByMultiplyingBy:number2];
5、除法运算
NSDecimalNumber *num = [number1 decimalNumberByDividingBy:number2];
6、比较
if ([number1 compare:number2] == NSOrderedAscending) {
NSLog(@"number1 < number2");
}else if([number1 compare:number2] ==NSOrderedDescending){
NSLog(@"number1 > number2");
}else if ([number1 compare:number2] == NSOrderedSame){
NSLog(@"number1 = number2");
}
7、指数运算
NSDecimalNumber *num = [number1 decimalNumberByMultiplyingByPowerOf10:2];// number1乘10的2次方
// + (NSDecimalNumber *)decimalNumberWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
// mantissa:长整形;exponent:指数;flag:正负数。
NSDecimalNumber *subtotalAmount = [NSDecimalNumber decimalNumberWithMantissa:123 exponent:-2 isNegative:NO];// 1.23
8、次方运算
NSDecimalNumber *num = [number1 decimalNumberByRaisingToPower:2];// number1的2次方
二、保留小数位数及四舍五入
1、NSDecimalNumberHandler
NSDecimalNumberHandler *handler =[NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode: NSRoundPlain
scale:2
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
[num decimalNumberByRoundingAccordingToBehavior:handler];
2、NSRoundingMode
NSRoundPlain, // Round up on a tie 四舍五入
NSRoundDown, // Always down == truncate 向下保留
NSRoundUp, // Always up 向上保留
NSRoundBankers // on a tie round so last digit is even (也是四舍五入,这是和NSRoundPlain不一样,如果精确的哪位是5,
它要看精确度的前一位是偶数还是奇数,如果是奇数,则入,偶数则舍,例如精确到小数点后两位, NSDecimalNumber 为1.225时,
NSRoundPlain结果为1.23,而NSRoundBankers则是1.22;NSDecimalNumber 为1.235时,均为1.24)
3、scale 保留小数个数
4、其它:溢出等是否报错