繁体   English   中英

NSDecimalNumber用于财务

[英]NSDecimalNumber for finances

我正在构建一个处理金钱的应用程序,并且到目前为止,我一直在使用浮点运算,但是我了解到最好使用NSDecimalNumber。

我想确保我已经正确理解了,所以这里是:

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

@property (nonatomic) float hourlyRate;

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

但是我现在将其更改为:

@property (nonatomic) NSDecimalNumber *hourlyRate;

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

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

假设此人在10:01进入工作场所。 我这样保存该信息:

[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:@"start"];

完成人员操作后,将从NSUserDefaults中读取开始时间,如下所示:

NSDate *start = [[NSUserDefaults standardUserDefaults] objectForKey:@"start"];

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

NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:start] / 3600;

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

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

谢谢!

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

是。 但是,您不需要强制转换结果。 所以它应该看起来像这样:

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

除非您使用的是非当前语言环境,否则不需要NSLocale部分:

settingsObject.hourlyRate = [NSDecimalNumber decimalNumberWithString:self.rateTextField.text];

我认为此函数不喜欢nil值,因此您需要确保rateTextField具有非nil值:

if ([self.rateTextField hasText]) {
    settingsObject.hourlyRate = [NSDecimalNumber decimalNumberWithString:self.rateTextField.text];
}
else {
    settingsObject.hourlyRate = [NSDecimalNumber zero];
}

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

是的,您将间隔转换为NSDecimal数,然后对我来说乘法看起来不错。

首先,您需要针对以下问题的答案:

您想达到的准确度-还是您需要达到的准确度?

您的应用会生成发票还是作为发票的基础? 如果是,则可能必须远离浮点数。 您可能还需要考虑在计算中实际使用持续时间的方式。 某些业务领域或专业可能有规定,这些规定定义了如何度量/开具发票时间。

不太准确:

如果您不需要非常准确,我会继续使用浮点数,直到遇到障碍为止。

准确:

1.金钱:

将钱存储为整数(分)。

2.时间:

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

3.计算:

使用整数进行计算。 切勿使用浮子。


细节:

当您输入25.07 (我使用了不同于20.57的数字来解释美分渲染),则将其存储为2507 用美分来计算。 用于显示转换为$$/hrs 例如:

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分钟。 在几分钟内存在类似的问题-假定这些值:

Actual Time | "Integer Time"
10:09:59    |  10:09
10:10:01    |  10:10
Difference:
00:00:02    |  00:01

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

如果您需要非常准确,则很难进行财务和时间计算。 因此,可以归结为:首先找出您需要的精度。 (请注意,“准确”在进入法规,法律等领域时可能具有怪异的含义和含义。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM