货币价格计算相关的NSDecimalNumber
来源:互联网 发布:前端调用接口js加密 编辑:程序博客网 时间:2024/04/29 18:28
在iOS开发中,和货币价格计算相关的,需要注意计算精度的问题。即使只是两位小数,也会出现误差。使用float类型运算,是完全不够的。经过一番测试,最后选择使用系统提供的API的NSDecimalNumber来进行更好的解决。
作为一个对外的库,鉴于版本延续,我们保留对外的flaot的类型,不改变接口,选择进行内部适配。
以下是一些基本的测试,
原始数据
1
2
3
2
3
float a = 0.01;
int b = 99999999;
double c = 0.0;
int b = 99999999;
double c = 0.0;
1:使用浮点运算
1
2
3
2
3
c = a*b;
NSLog(@"%f",c);
NSLog(@"%.2f",c);
NSLog(@"%f",c);
NSLog(@"%.2f",c);
使用double类型存储没有触及问题的实质,完全不能解决。
1
2
2
2011-12-30 11:04:00.121 Untitled[2912:207] 1000000.000000
2011-12-30 11:04:00.123 Untitled[2912:207] 1000000.00
2011-12-30 11:04:00.123 Untitled[2912:207] 1000000.00
2:使用类型转换,提高精度
1
2
3
2
3
c = a*(double)b;
NSLog(@"%f",c);
NSLog(@"%.2f",c);
NSLog(@"%f",c);
NSLog(@"%.2f",c);
Double运算的精度是提高了,可是浮点数的数值早已经出现了精度的不准确,即使存储空间足够,同样还是不准确的数值。
1
2
2
2011-12-30 11:04:00.123 Untitled[2912:207] 999999.967648
2011-12-30 11:04:00.124 Untitled[2912:207] 999999.97
2011-12-30 11:04:00.124 Untitled[2912:207] 999999.97
3:通过和NSString的转换
将计算的原始数据转换为纯粹的double类型的数据,这样的计算精度就可以达到要求了。
1
2
3
4
2
3
4
NSString *objA = [NSString stringWithFormat:@"%.2f", a];
NSString *objB = [NSString stringWithFormat:@"%.2f", (double)b];
c = [objA doubleValue] * [objB doubleValue];
NSLog(@"%.2f",c);
NSString *objB = [NSString stringWithFormat:@"%.2f", (double)b];
c = [objA doubleValue] * [objB doubleValue];
NSLog(@"%.2f",c);
计算的结果还是比较准确的,不过需要做格式化输入和格式化输出的处理。同时使用NSString来转换,这样的写法看起来比较奇怪。
1
2011-12-30 11:04:00.190 Untitled[2912:207] 999999.99
4:个人还是比较喜欢使用系统提供的类型来进行计算
通过NSDecimalNumber提供的计算方式,可以很好的计算出准确的精度的数据,同时不需要使用格式化输出等。
其计算的精度是比较高,这是官方建议的货币计算的API,对乘除等计算都有单独的API接口来提供。
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
NSString *decimalNumberMutiplyWithString(NSString *multiplierValue,NSString *multiplicandValue)
{
NSDecimalNumber *multiplierNumber = [NSDecimalNumber decimalNumberWithString:multiplierValue];
NSDecimalNumber *multiplicandNumber = [NSDecimalNumber decimalNumberWithString:multiplicandValue];
NSDecimalNumber *product = [multiplicandNumber decimalNumberByMultiplyingBy:multiplierNumber];
return [product stringValue];
}
NSLog(@"%@",decimalNumberMutiplyWithString([NSString stringWithFormat:@"%f",a], [NSString stringWithFormat:@"%d",b]));
{
NSDecimalNumber *multiplierNumber = [NSDecimalNumber decimalNumberWithString:multiplierValue];
NSDecimalNumber *multiplicandNumber = [NSDecimalNumber decimalNumberWithString:multiplicandValue];
NSDecimalNumber *product = [multiplicandNumber decimalNumberByMultiplyingBy:multiplierNumber];
return [product stringValue];
}
NSLog(@"%@",decimalNumberMutiplyWithString([NSString stringWithFormat:@"%f",a], [NSString stringWithFormat:@"%d",b]));
1
2011-12-30 11:04:00.251 Untitled[2912:207] 999999.99
只是测试,所以接口名大致写写,名字取得比较不那么讲究,希望可以表达清楚。
总的来说,对于货币计算,应该需要注意精度的问题。同时在运算的时候,应该优先选用框架提供的API,否则,就应该使用足够精度的类型运算,同时对自己写的接口进行足够的说明,要求开发者按照规范来使用。
在自己不能保证足够准确的情况下,用适当的说明的要求来规避责任还是可以接受的。至少被人抱怨两句总比出错强。
- 货币价格计算相关的NSDecimalNumber
- Objective-C精确的货币计算 NSDecimalNumber
- iOS NSDecimalNumber--货币计算
- iOS NSDecimalNumber 货币计算 四舍五入
- iOS NSDecimalNumber 货币计算 四舍五入
- iOS开发之NSDecimalNumber的使用,货币计算/精确数值计算/保留位数等
- NSDecimalNumber 金额数据的精确计算
- iOS NSDecimalNumber金钱方面的计算
- 货币金额的计算
- 货币金额的计算
- 价格弹性的计算()
- 价格的计算---BigDecimal
- 精度计算——NSDecimalNumber的使用和封装!
- 解决货币精度问题(NSDecimalNumber)
- iOS 笔记 精确计算 NSDecimalNumber
- ios 精确的货币计算
- 远期外汇价格的计算
- iOS NSDecimalNumber的基本知识
- 【Android开发学习35】GL_TRIANGLE_STRIP之纹理贴图
- 计算机操作系统01-引论
- linux驱动头文件说明
- 信息论的简单应用
- Java Feture 简介
- 货币价格计算相关的NSDecimalNumber
- ip_route_input() -- IP路由(输入路由)
- 数组操作
- 带偏移限制的视差贴图
- iOS 6 SDK: 在应用内展示App Store --- 用户可以 不必 关闭应用直接在应用内评价
- Java EE开发环境搭建
- SQL Server 2005为数据库设置用户名和密码的方法
- 关于uitabbaritem图片显示
- Kvo