首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >财务NSDecimalNumber

财务NSDecimalNumber
EN

Stack Overflow用户
提问于 2015-06-04 14:41:15
回答 2查看 223关注 0票数 0

我正在开发一个处理货币的应用程序,到目前为止我一直在使用浮点算法,但我已经学会了使用NSDecimalNumber更好。

我想确保我已经正确地理解了它,下面是:

想象一下某个工人,每小时收入20.57美元。此信息由用户提供。我以前是这样做的:

代码语言:javascript
复制
@property (nonatomic) float hourlyRate;

NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *hourlyRate = [numberFormatter numberFromString:self.rateTextField.text];
settingsObject.hourlyRate = [hourlyRate floatValue];

但我现在把它改为:

代码语言:javascript
复制
@property (nonatomic) NSDecimalNumber *hourlyRate;

settingsObject.hourlyRate = (NSDecimalNumber *)[NSDecimalNumber decimalNumberWithString:self.rateTextField.text locale:[NSLocale currentLocale]];

这是从字符串读取NSDecimalNumbers的正确方法吗?

假设这个人在10:01进入工作场所。我保存这些信息的方式如下:

代码语言:javascript
复制
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"start"];

完成后,从NSUserDefaults中读取开始时间如下:

代码语言:javascript
复制
NSDate *start = [[NSUserDefaults standardUserDefaults] objectForKey:@"start"];

计算持续时间的方法如下:

代码语言:javascript
复制
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:start] / 3600;

NSDecimalNumber *earned = [settingsObject.hourlyRate decimalNumberByMultiplyingBy:[[NSDecimalNumber alloc] initWithFloat:interval]];

,这是正确和最有效的方法,同时又保持精度吗?

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2015-06-04 17:42:48

这是从字符串读取NSDecimalNumbers的正确方法吗?

是。但是,您不需要抛出结果。所以应该是这样的:

代码语言:javascript
复制
settingsObject.hourlyRate = [NSDecimalNumber decimalNumberWithString:self.rateTextField.text locale:[NSLocale currentLocale]];

并且NSLocale部分是不必要的,除非您使用的是非当前区域设置:

代码语言:javascript
复制
settingsObject.hourlyRate = [NSDecimalNumber decimalNumberWithString:self.rateTextField.text];

我认为这个函数不喜欢零值,所以您需要首先确保rateTextField有一个非零值:

代码语言:javascript
复制
if ([self.rateTextField hasText]) {
    settingsObject.hourlyRate = [NSDecimalNumber decimalNumberWithString:self.rateTextField.text];
}
else {
    settingsObject.hourlyRate = [NSDecimalNumber zero];
}

这是正确和最有效的方法,同时保持精确吗?

是的,你把间隔转换成一个NSDecimal数,然后乘法对我来说很好。

票数 0
EN

Stack Overflow用户

发布于 2015-06-04 18:45:57

首先,您需要回答这个问题:

你想要多精确--或者你需要多精确?

您的应用程序是生成发票,还是它作为发票的基础?如果是,你可能必须远离浮点数。您可能还必须考虑如何在计算中实际使用持续时间。对某些业务领域或专业可能有规定,其中规定了如何衡量/发票时间。

不太准确:

如果你不需要真的准确,我会继续使用浮动数字,直到你遇到障碍。

精确度:

1.货币:

把钱以整数的形式储存为美分。

2.时间:

确定时隙并将其存储为整数(可能是分钟)。

3.计算:

使用整数计算。千万不要用浮标。

详细信息:

当您有像25.07这样的输入时(我使用了与您的20.57不同的数字来解释美分呈现),将其存储为2507。以美分为单位计算。用于显示转换为$$/hrs。例如:

代码语言:javascript
复制
int amount = 2507;
int amountDollars = amount / 100;
int amountCents = amount % 100;

NSString *output = [NSString stringWithFormat:@"%d.%02d $/hrs", amountDollars, amountCents];
NSLog(@"output = %@", output);
// prints:
// output = 25.07 $/hrs

时间选择一个合适的基本单位(分钟/秒/五分钟/十分钟/半小时?)并将其存储为整数。

让我们假设您的发票单位为10分钟。然后,你可能会在接下来的10分钟,当他们开始。所以,如果有11分钟的记录,你必须计算20分钟。类似的问题持续了几分钟--假设这些值:

代码语言:javascript
复制
Actual Time | "Integer Time"
10:09:59    |  10:09
10:10:01    |  10:10
Difference:
00:00:02    |  00:01

如果您只是使用实际时间使用浮点数,第一个差异几乎等于什么-第二个等于一分钟。如果您的时间在报告中显示为10:0910:10,人们会问,为什么在第一种情况下,金额几乎为零。

如果你需要准确的话,做财务和时间计算是很困难的。因此,它归结为:首先,找出你需要有多精确。(请注意,当进入法规、法律等领域时,“准确”可能有奇怪的含义和含义)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30646932

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档