long priceA = 1599;
long priceB = 1269;
System.out.println("Bill total: €" + formatCents(priceA + priceB));
工作很好,其中formatCents来自库或如果需要手写:
public String formatCents(long v) {
boolean sign = v >= 0;
if (!sign) v = -v;
int wholes = v / 100;
int parts = v % 100;
return String.format("%s%d.%02d", sign ? " " : "-", wholes, parts);
}
2条答案
按热度按时间a8jjtwal1#
我尝试了
parseDouble
,DecimalFormat
,它能够提供我预期的答案。src
测试(通过)
qacovj5a2#
这个答案分为三个部分:
double不准确
拿一张纸。
写下1除以5的结果。用十进制形式写下来。你要写“0。2“把它还给我。
到目前为止,一切顺利。
现在做同样的事情,但这次,写下1除以3。
你会发现这是不可能的你写0。333333...最终你用完了纸上的空间来写更多的三。你把它还给我,数字有点不准确。
double
是相同的东西。但计算机是十进制的。1/5适合而1/3不适合的原因是因为我们是用十进制(基数为10)来写的,而5“很适合”10,但3不适合。基于同样的原因,你可以写下1/2(0。5 -因为2适合10)。解释为什么1/4适合稍微有点问题(4不能很好地适合10,但是一旦你写下适合的部分,也就是1/5,剩下1/20,20可以很好地适合10)-但同样的原则适用。计算机以2为基数计数。这很烦人--而能很好地划分成10的东西是1,2,5,10,而任何可以分解成这些数字的因子的东西,以2为基数,它就是 * 1和2。所以1/2,1/4,1/8,5/16 -这些都是“完美”的,但即使是像0这样简单的东西。1(1/10)不适合。
见证人:
如果你不知道这个四舍五入业务,上面的结果会令人惊讶。它不打印1。0(而不是0。9999999),并且它也不打印'true' -相反,它打印false。这很奇怪.10 * 0.1显然是1。0.
你在这里被杀了。这就像我让你在一张纸条上写上“1/3”,再做两次,然后让你把这三张纸条上的数字加起来--这已经不是1了。0,而不是0。999999999(不是无限的,只是很多,而是有限的9),不等于1。0.
换一种完全不同的方式来思考:
double
由64位表示。假设我给了你3个开关,你存储信息的唯一方法是让开关处于向上或向下状态。你可以“记住”8个独特的事件:000、001、010、011、100、101、110和111。就是这样。和doubles一样,但不是8(2的3次方),而是一个巨大的数字:2的64次方。
但这仍然是你能记住的唯一的东西,在0和1之间有无限数量的数字,更不用说-和+无穷之间,这就是double或多或少过度简化所能表示的。
double实际上只能表示略少于2^64个唯一数。让我们称之为“受祝福”的数字。对于任何未被祝福的数字,double math默默地舍入到最近的祝福数字。幸运的数字不是均匀分布的:在1.0附近有很多,当你远离1时。0的人越来越少。
如何使用double?
记住他们有轻微的错误。这表现在三个方面:
String.format
或类似格式。如果我将上面的代码稍微修改为:
它打印1。000,因为我们拥有的双倍(0.999999999999999764左右)确实舍入到1。000如果我们明确地说:请最多保留3位小数。
它总是不正确的,只是打印一个双精度,任何地方,除非你明确地希望呈现错误。相反,在渲染时始终使用一些舍入。
在比较时,请记住错误,并使用“增量比较”。与其问“
a
和b
相等”,不如问“a
和b
之间的绝对差很小吗?”’。这是如何:这将打印所需的
true
。但是,你仍然在玩弄事实,有不准确的地方。
完美和
BigDecimal
BigDecimal完美地以十进制表示数字。缺点是,它们非常慢。幸运的是,计算机的速度非常快,所以这通常不重要。
它们也有数学本身的缺点:如果你试图在BigDecimal数学中用1除以3,除非你告诉它舍入,否则它会抛出一个异常。...让你再次圆了。至少它的控制,但仍然。
通常,如果你试图建模具有不同原子单位的东西,最好是将这些原子存储在
long
中。例如,在大多数情况下,存储货币的最佳方式是美分。存储账单总计2篇文章,其中一篇花费15欧元。99欧元,另一个12欧元。六十九:工作很好,其中formatCents来自库或如果需要手写:
每种货币都有原子单位。日元只是日元,美元和欧元有美分,甚至比特币也有satoshis。