文档章节

iOS开发:Objective-C精确的货币计算

秦无炎
 秦无炎
发布于 2017/05/08 13:44
字数 749
阅读 12
收藏 0
点赞 0
评论 0

      在iOS开发中,和货币价格计算相关的,需要注意计算精度的问题。即使只是两位小数,也会出现误差。使用float类型运算,是完全不够的。经过一番测试,最后选择使用系统提供的API的NSDecimalNumber来进行更好的解决。

作为一个对外的库,鉴于版本延续,我们保留对外的flaot的类型,不改变接口,选择进行内部适配。

以下是一些基本的测试,

原始数据

 

float a = 0.01;

int b = 99999999;

double c = 0.0;

 

1:使用浮点运算,

 

c = a*b;

NSLog(@"%f",c);

NSLog(@"%.2f",c);

 

使用double类型存储没有触及问题的实质,完全不能解决。

 

2011-12-30 11:04:00.121 Untitled[2912:207] 1000000.000000

2011-12-30 11:04:00.123 Untitled[2912:207] 1000000.00

 

 

2:使用类型转换,提高精度

 

c = a*(double)b;

NSLog(@"%f",c);

NSLog(@"%.2f",c);

 

Double运算的精度是提高了,可是浮点数的数值早已经出现了精度的不准确,即使存储空间足够,同样还是不准确的数值。

 

2011-12-30 11:04:00.123 Untitled[2912:207] 999999.967648

2011-12-30 11:04:00.124 Untitled[2912:207] 999999.97

 

 

3:通过和NSString的转换,将计算的原始数据转换为纯粹的double类型的数据,这样的计算精度就可以达到要求了。

 

NSString *objA = [NSString stringWithFormat:@"%.2f", a];

NSString *objB = [NSString stringWithFormat:@"%.2f", (double)b];

c = [objA doubleValue] * [objB doubleValue];

NSLog(@"%.2f",c);

 

计算的结果还是比较准确的,不过需要做格式化输入和格式化输出的处理。同时使用NSString来转换,这样的写法看起来比较奇怪。

 

2011-12-30 11:04:00.190 Untitled[2912:207] 999999.99

 

 

4:个人还是比较喜欢使用系统提供的类型来进行计算。通过NSDecimalNumber提供的计算方式,可以很好的计算出准确的精度的数据,同时不需要使用格式化输出等。

其计算的精度是比较高,这是官方建议的货币计算的API,对乘除等计算都有单独的API接口来提供。

 

NSString *decimalNumberMutiplyWithString(NSString *multiplierValue,NSString *multiplicandValue)

{

     NSDecimalNumber *multiplierNumber = [NSDecimalNumberdecimalNumberWithString:multiplierValue];

     NSDecimalNumber *multiplicandNumber = [NSDecimalNumberdecimalNumberWithString:multiplicandValue];

     NSDecimalNumber *product = [multiplicandNumber decimalNumberByMultiplyingBy:multiplierNumber];

     return [product stringValue];

}

 

NSLog(@"%@",decimalNumberMutiplyWithString([NSString stringWithFormat:@"%f",a], [NSString stringWithFormat:@"%d",b]));

 

 

 

2011-12-30 11:04:00.251 Untitled[2912:207] 999999.99

 

 

只是测试,所以接口名大致写写,名字取得比较不那么讲究,希望可以表达清楚。

 

总的来说,对于货币计算,应该需要注意精度的问题。同时在运算的时候,应该优先选用框架提供的API,否则,就应该使用足够精度的类型运算,同时对自己写的接口进行足够的说明,要求开发者按照规范来使用。

在自己不能保证足够准确的情况下,用适当的说明的要求来规避责任还是可以接受的。至少被人抱怨两句总比出错强。

 

本文出自 “ArthurChen” 博客,出处http://arthurchen.blog.51cto.com/2483760/761426

本文转载自:

共有 人打赏支持
秦无炎
粉丝 4
博文 120
码字总数 4984
作品 0
朝阳
程序员
10个优秀Objective-C和iOS开发在线视频教程

如果你自己开发iOS应用,你肯定会发现网上有很多资源。学习编程的一个最好的方法就是自己写代码,而开始写代码的最快的方式就是看其他人怎么写。我们从海量视频和学习网站中整理出了我们认为...

mingxun
2014/05/09
0
0
那些在学习iOS开发前就应该知道的事(part 1)

英文原文:Things I wish I had known before starting iOS development—Part 1 设计师设计出来了一个不错的引导界面,然而当我看到设计稿的时候,我们的app也没几天就要上线了。这个界面模...

TomatosX
2015/06/12
0
0
我是直接学Swift还是Objective-C?

当我们发布了Swift语言学习课程之后,收到了很多邮件和私信来问自己是否还需要学习C或者Objective-C。此外,人们似乎还在迷惑Swift到底适合iOS开发生态中的哪些部分。通过这篇文章,我希望能...

程序袁_绪龙
2014/09/25
0
2
IOS学习笔记——Objective-c基础(一)

最近自学ios,ios的支持语言是Objective-c,所以要学习ios就需要先学习Objective-c语言。当掌握了Objective-c的基础知识之后,我们就可以入手学习iOS开发做出一些自己的应用。 我现在还是...

丛林迷雾
2012/12/30
0
1
那些在学习iOS开发前就应该知道的事(part 2)

英文原文:Things I wish I had known before starting iOS development—Part 2 如果你还没读这篇文章的第一部分,请先读完了再来看第二部分。 那些在学习iOS开发前就应该知道的事(part 1)...

TomatosX
2015/06/12
0
0
如何通过 Common Lisp 调用 iOS simulator 并交互?== 未解决

之前根据 CCL 的教程学会了如何在 Common Lisp 中调用 Cocoa 框架,编写 MAC 应用程序。 最近在考虑如何通过 Common Lisp 调用 Cocoa Touch 框架,开发 iOS 程序(iPhone/iPad),首先需要解...

FreeBlues
2014/06/23
0
0
如何判断你是合格的高级iOS开发工程师?

前言 随着移动互联网的高速发展泄洪而来,有意学习移动开发的人越来越多了,竞争也是越来越大,需要学习的东西很多。如何才能在激烈的移动开发者竞争中一枝独秀,成为一名真正合格的高级iOS...

_小迷糊
05/26
0
0
再看知名应用背后的第三方开源项目

知名应用程序的设计和技术一直都是开发者需要学习的,同样这些应用所使用的开源框架也是不可忽视的一部分。此前《iOS第三方开源库的吐槽和备忘》中作者ibireme列举了国内多款知名应用所使用的...

hejunbinlan
2015/08/18
0
0
(转)直接拿来用!最火的iOS开源项目(二)

“每一次的改变总意味着新的开始。”这句话用在iOS上可谓是再合适不过的了。GitHub上的iOS开源项目数不胜数,iOS每一次的改变,总会引发iOS开源项目的演变,从iOS 1.x到如今的iOS 7,有的项目...

孙启超
2013/06/21
0
1
ios时间那点事--NSLocale

iOS时间那点事 NSLocale 若你只开发中国区的应用,需要保证用户修改当前语言环境时应用的显示不发生变化。而像NSDateFormatter这样的类,会根据设备的设置,自动返回不同语言的数据。为了保证...

JustBen
2013/08/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Android 复制和粘贴功能

做了一回搬运工,原文地址:https://blog.csdn.net/kennethyo/article/details/76602765 Android 复制和粘贴功能,需要调用系统服务ClipboardManager来实现。 ClipboardManager mClipboardM...

她叫我小渝
30分钟前
0
0
拦截SQLSERVER的SSL加密通道替换传输过程中的用户名密码实现运维审计(一)

工作准备 •一台SQLSERVER 2005/SQLSERVER 2008服务 •SQLSERVER jdbc驱动程序 •Java开发环境eclipse + jdk1.8 •java反编译工具JD-Core 反编译JDBC分析SQLSERVER客户端与服务器通信原理 SQ...

紅顏為君笑
47分钟前
4
0
jQuery零基础入门——(六)修改DOM结构

《jQuery零基础入门》系列博文是在廖雪峰老师的博文基础上,可能补充了个人的理解和日常遇到的点,用我的理解表述出来,主干出处来自廖雪峰老师的技术分享。 在《零基础入门JavaScript》的时...

JandenMa
今天
0
0
linux mint 1.9 qq 安装

转: https://www.jianshu.com/p/cdc3d03c144d 1. 下载 qq 轻聊版,可在百度搜索后下载 QQ7.9Light.exe 2. 去wine的官网(https://wiki.winehq.org/Ubuntu) 安装 wine . 提醒网页可以切换成中...

Canaan_
今天
0
0
PHP后台运行命令并管理运行程序

php后台运行命令并管理后台运行程序 class ProcessModel{ private $pid; private $command; private $resultToFile = ''; public function __construct($cl=false){......

colin_86
今天
1
0
数据结构与算法4

在此程序中,HighArray类中的find()方法用数据项的值作为参数传递,它的返回值决定是否找到此数据项。 insert()方法向数组下一个空位置放置一个新的数据项。一个名为nElems的字段跟踪记录着...

沉迷于编程的小菜菜
今天
1
1
fiddler安装和基本使用以及代理设置

项目需求 由于开发过程中客户端和服务器数据交互非常频繁,有时候服务端需要知道客户端调用接口传了哪些参数过来,这个时候就需要一个工具可以监听这些接口请求参数,已经接口的响应的数据,这种...

银装素裹
今天
0
0
Python分析《我不是药神》豆瓣评论

读取 Mongo 中的短评数据,进行中文分词 对分词结果取 Top50 生成词云 生成词云效果 看来网上关于 我不是药神 vs 达拉斯 的争论很热啊。关于词频统计就这些,代码中也会完成一些其它的分析任...

猫咪编程
今天
0
0
虚拟机怎么安装vmware tools

https://blog.csdn.net/tjcwt2011/article/details/72638977

AndyZhouX
昨天
1
0
There is no session with id[xxx]

参考网页 https://blog.csdn.net/caimengyuan/article/details/52526765 报错 2018-07-19 23:04:35,330 [http-nio-1008-exec-8] DEBUG [org.apache.shiro.web.servlet.SimpleCookie] - Found......

karma123
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部