[英]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:09
和10:10
,人们会感到奇怪,为什么在第一种情况下金额几乎为零。
如果您需要非常准确,则很难进行财务和时间计算。 因此,可以归结为:首先找出您需要的精度。 (请注意,“准确”在进入法规,法律等领域时可能具有怪异的含义和含义。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.