【问题标题】:rounding in base 10以 10 为底四舍五入
【发布时间】:2014-07-03 05:30:05
【问题描述】:

我有一个函数可以将给函数的数字四舍五入到最接近的整数便士。

<script type='text/javascript'>
Math.roundNumber = function(a,b){
    if(!isNaN(parseInt(a))){
        c = Math.pow(10,b);
        return (Math.round(a*c)/c);
    }
    return false;
}
</script>

但是我注意到输入到函数中的上述数字只能四舍五入到最接近的一便士,但必须四舍五入到小数点后两位。

例如

15.236562213541684 = 15.24 9846.65456169846 = 9846.66

我认为这只是一个改变的例子 返回 (Math.round(ac)/c); 至 返回 (Math.ceil(ac)/c);

显然我错了。

这件事有什么帮助吗?

** 编辑 **

这是我正在尝试实现的公式,也许它会有所帮助

a = intrest price
b = terms
c = a/b
d = c*(b-1)
e = a-d

例如

a = 295.30
b = 156
c = 295.30/156 = 1.90 (rounded up to nearest decimal as above)
d = 1.90 * (b-1) = 294.50
e = 295.30 - 294.50 = 0.80

任何人都可以正确执行上述操作吗?

Here 是我拥有的当前代码的链接,包括公式...这是我第一次启动 JavaScript 时制定的一个非常古老的公式(现在是不久前)但是我现在仍然没有更好就像我那时一样。

任何人都可以清理它,看看他们是否可以看到为什么它不能与上面的功能匹配?

【问题讨论】:

  • “显然我错了。”例子?
  • 我认为您的代码确实有效。也许你缓存了一个旧脚本?
  • 上面使用的 parseInt() 如果数字以零开头,则会产生意想不到的结果

标签: javascript math number-manipulation


【解决方案1】:

这个已经有内置函数了,Number.toFixed(numDigits),为什么不用这个呢?

参数:数字
小数点后出现的位数;这可以是 0 到 20 之间的值,包括 0 和 20,并且实现可以选择支持更大范围的值。如果省略此参数,则将其视为 0。

回报:
数字的字符串表示形式,不使用指数表示法,并且在小数点后具有精确的数字。必要时对数字进行四舍五入,必要时用零填充小数部分,使其具有指定的长度。如果 number 大于 1e+21,此方法只需调用 Number.toString() 并以指数表示法返回一个字符串。

例子:

>>> new Number(15.236562213541684).toFixed(2);
"15.24"
>>> new Number(9846.65456169846).toFixed(2);
"9846.65"

最后一个与您的示例不匹配 - 9846.65456169846 四舍五入到小数点后两位应该是 9846.65,而不是 9846.66

【讨论】:

  • toFixed 向下舍入。它比他的 Math.round 解决方案要好,但仍然无法按要求工作。
  • "最后一个与您的示例不匹配 - 9846.65456169846 四舍五入到小数点后两位应该是 9846.65,而不是 9846.66。" - 这是不正确的,因为我提到它需要始终向上舍入到最接近的一便士。
  • 啊我没明白他的意思。
  • @scragar: toFixed() 不会向下取整,但它使用浮点表示,因此可能会产生意想不到的结果;此外,还有一个 IE 错误 - 请参阅 stackoverflow.com/questions/661562/…
【解决方案2】:

您的代码比您执行此任务所需的更复杂。如果您知道小数点始终代表一个稳定的值,而不管该小数点两侧的数字长度如何,那么您很幸运。

1) 那么您只需将原始数字乘以 100

2) if (Number(x.charAt(indexOF(".") + 1)) > 4) {x += 1} 其中 x 是你的数字

3) parseInt

4) 除以 100 即可完成。

【讨论】:

  • “如果你知道小数点总是代表一个稳定的值,不管小数点两边的数字长度如何,你很幸运。” - 请详细说明您的意思?
【解决方案3】:

使用定点算术的建议是很好的建议。不幸的是,Javascript 中没有定点运算——所有数字都是双精度浮点数。 (好吧,如果不引入一些显式支持库,就没有定点算术。)

为了清除文本字段中的输入,我已经开始将数字作为字符串处理(尽可能地)。将输入分成小数点左右的部分,然后以整数值工作(必要时通过 Math.floor() )。如果您必须处理小数点后第二位的杂散数字,要么将它们视为错误(它们到底是什么意思?),要么再次将它们分开并将它们作为整数处理。

如果您处理用户提供的值(即来自文本输入字段的内容),那么您真的不应该在 Javascript 中执行此操作,因为再一次,您不需要没有你真正需要的数字工具。

【讨论】:

  • 在 JS 中可能没有专门的定点运算,但你总是可以将所有值乘以适当的因子得到整数;只要您不耗尽双精度的 53 位精度,数学将是准确的
【解决方案4】:

Math.ceil() 替换Math.round() 应该可以工作:错误一定在其他地方。

另外,我建议完全放弃isNaN(parseInt()),因为无论如何数学函数都会转换为数字,如果不可能,则返回NaN。这将导致函数也返回NaN,这比布尔值false 更适合。

顺便说一句:将浮点数学与货币值一起使用是个坏主意:改用定点算术!


现在我们知道您要做什么,下面是为您的示例计算所需值的代码:

var value = 295.30;
var count = 156;
var payment = Math.ceil(value * 100 / count) / 100;
var last_payment = Math.round((value - (count - 1) * payment) * 100) / 100;

将所有计算的 round() 更改为 ceil() 不起作用,因为必须正常舍入最后一次付款以补偿由于使用浮点值而导致的不准确性。

通常最好只使用整数数学,因此将所有值与100 相乘并仅在输出值时进行转换:

var value = 29530;
var count = 156;
var payment = Math.ceil(value / count);
// rounding no longer necessary as integer math is precise:
var last_payment = value - (count - 1) * payment;

【讨论】:

  • 我已经添加了我想弄清楚的公式......有什么想法吗?
【解决方案5】:
function currency_fix(number)
{
    var unfixed_number = Math.ceil(number.toFixed(5) * 100) / 100;
    return unfixed_number.toFixed(2)
}

var a = currency_fix(295.30)
var b = currency_fix(156)
var c = currency_fix(a / b)
var d = currency_fix(c * (b - 1))
var e = currency_fix(a - d)

document.write(
    'a = ' + a + '<br />' +
    'b = ' + b + '<br />' +
    'c = ' + c + '<br />' +
    'd = ' + d + '<br />' +
    'e = ' + e + '<br />'
)

// OUTPUT
//a = 295.30
//b = 156.00
//c = 1.90
//d = 294.50
//e = 0.80

在这种情况下,我得到了您想要的结果。不确定它是否每次都有效,但似乎有效。我肯定会先检查它是否按您的意愿工作。

【讨论】:

  • 很好地呈现...这包含了我所问的一切的概念...您以一种有意义的方式简单地呈现了它。感谢您花时间写这篇文章。
【解决方案6】:

不,你是对的。

我用 ceil 修改测试了你的代码,它可以工作。

【讨论】:

  • ceil 不起作用... 使用 ceil 似乎会产生不准确之处,例如利息价格:295.30 英镑 155 次付款为 1.90 英镑,然后一次付款为 0.81 英镑。加起来是 295.31,其中一笔付款必须是 0.80 英镑...
  • @Neil:因为你总是四舍五入,你当然会经常得到一个大于确切值总和的总和。即使四舍五入有时也会有所不同。如果您希望总额相同,则必须将最终付款计算为总额与先前实际付款总和之间的差额。
  • @Guffa 我明白这一点,如果您查看我在编辑中添加的内容,您会看到我正在尝试制作的实际公式......也许您可以看到数字需要在哪里应用此公式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 2012-08-04
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多