我正在构建一个处理金钱的应用程序,直到现在我一直在使用浮点运算,但我已经了解到使用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]];
这是正确而有效的方法,同时保持精确度吗?
谢谢!
答案 0 :(得分:0)
这是从字符串中读取NSDecimalNumbers的正确方法吗?
是。但是,您不需要转换结果。所以它应该是这样的:
settingsObject.hourlyRate = [NSDecimalNumber decimalNumberWithString:self.rateTextField.text locale:[NSLocale currentLocale]];
除非您使用的是非当前区域设置,否则NSLocale
部分不是必需的:
settingsObject.hourlyRate = [NSDecimalNumber decimalNumberWithString:self.rateTextField.text];
我不认为此函数喜欢nil值,因此您需要确保rateTextField
首先具有非零值:
if ([self.rateTextField hasText]) {
settingsObject.hourlyRate = [NSDecimalNumber decimalNumberWithString:self.rateTextField.text];
}
else {
settingsObject.hourlyRate = [NSDecimalNumber zero];
}
这是正确而有效的方法,同时保持精确度吗?
是的,您将间隔转换为NSDecimal数字然后乘法对我来说很好。
答案 1 :(得分:0)
首先,您需要回答这个问题:
您希望成为多么准确 - 或者您需要做到?
您的应用会生成发票,还是作为发票的基础?如果是,您可能必须远离浮点数。您可能还需要考虑如何在计算中实际使用持续时间。可能存在某些业务领域或专业的法规,这些法规定义了如何衡量/开具发票时间。
不太准确:
如果你不需要非常准确,我会继续使用浮动数字直到遇到障碍物。
<强>准确强>
<强> 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
,那么人们会想知道,为什么在第一种情况下数量几乎为零。
如果您需要非常准确,那么进行财务和时间计算很难。所以归结为:第一,找出你需要的准确度。 (注意&#34;准确&#34;在进入法规,法律等领域时可能具有奇怪的含义和含义。)