2

这里的菜鸟想计算 iPhone 上的复利。

float principal;
float rate;
int compoundPerYear;
int years;
float amount;

公式应该是:金额=本金*(1+利率/每年复合)^(利率*年)

我得到稍微不正确的答案:

amount = principal*pow((1+(rate/compoundPerYear)), (compoundPerYear*years));

我正在以 0.1 的速率对其进行测试,但调试器报告 .100000001 。

我做错了吗?我应该使用双打还是特殊课程(例如,NSNumber)?

感谢您的任何其他想法!


经过进一步研究,似乎 NSDecimalNumber 类可能正是我所需要的。现在我只需要弄清楚如何使用这个坏男孩。

4

2 回答 2

6

double会让你更接近,但你不能用二进制精确表示 1/10(无论如何使用 IEEE 浮点表示法)。

如果你真的有兴趣,可以看看What Every Computer Scientist Should Know About Floating-Point Arithmetic。链接可耻地从另一个 SO 线程中窃取。

快速而肮脏的解释是,浮点数以二进制形式存储,其中的位表示 2 的小数幂(1/2、1/4、1/8,...)。根本没有数学方法可以将这些分数加起来正好为 1/10,因此 0.1 不能用 IEEE 浮点表示法精确表示。

double通过在基数之前/之后为您提供更多数字来扩展数字的准确性,但它不会以可以弥补这一点的方式改变二进制文件的格式。你很可能会在稍后的某个地方得到额外的一点。

也可以看看:

和其他类似的线程。


我在下班回家的路上仔细考虑了进一步的扩展:可以想象的一种处理方法是仅以美分(作为 int)表示所有货币值,然后在显示数据时转换为 $.cents 格式。这实际上也很容易,因为您可以在转换时利用整数除法的截断:

int interest, dollars, cents;
interest = 16034; //$160.34, in cents
dollars = value / 100; //The 34 gets truncated: dollars == 160
cents = value % 100; //cents == 34
printf("Interest earned to date: $%d.%d\n", dollars, cents);

我不了解 Objective-C,但希望这个 C 示例也有意义。同样,这只是处理它的一种方法。它还可以通过在需要显示数据时进行字符串格式化的函数来改进。

您显然可以想出自己的(甚至更好!)方法来做到这一点,但也许这会帮助您入门。如果其他人对此有建议,我也想听听他们的意见!

于 2010-08-06T21:43:52.493 回答
2

简短的回答:永远不要使用浮点数来赚钱。

适用于大多数平台的简单方法是将货币表示为其最小单位的整数。最小的单位通常是美分,尽管通常 1/10 或 1/100 美分是真正的基本单位。

在许多平台上,还有可以表示定点小数的可用数字类型。

确保四舍五入正确。财务簿记经常使用银行家的四舍五入。

于 2010-08-07T12:33:43.580 回答