2009-10-01 46 views
1

我有一个函数可以将赋给函数的数字舍入到最近的整个便士。以10为底的舍入

<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> 

但它已经到了我的注意,输入到该函数的表示号码只能四舍五入到最接近的一个便士但是它必须四舍五入至小数点后两位。

E.G.

 
15.236562213541684 would = 15.24 
9846.65456169846 would = 9846.66 

我认为这将只是改变 回报(Math.round(一)/ C)的情况; 返回 return(Math.ceil(a c)/ 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时(这是前一段时间现在),但我仍然没有更好的现在作为那时我回来了。

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

+1

“显然我错了。” 例子? – 2009-10-01 17:00:41

+1

我认为你的代码实际上工作。也许你有一个旧脚本缓存? – 2009-10-01 17:23:49

+0

上面使用的parseInt()会给出意想不到的结果,如果该数字以固定为零的ZERO – 2009-10-01 19:27:11

回答

0
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 

我在这种情况下得到了你想要的结果。不知道它是否会每次都起作用,但看起来似乎。我肯定会检查它的工作,因为你想要它第一。

+0

......这将我提出的所有东西都放在了概念之中......你只是以一种合理的方式呈现它。感谢您花时间写这篇文章。 – 2009-10-01 19:30:36

5

这里有一个内置函数,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

+1

也向下舍入。这比他的Math.round解决方案更好,但它仍然不能按要求工作。 “ – scragar 2009-10-01 16:48:18

+1

”这最后一个与您的示例不符 - 9846.65456169846舍入到小数点后两位应该是9846.65,而不是9846.66。“ - 这是不正确的,因为我提到它需要总是舍入到最近的一个便士。 – 2009-10-01 16:50:51

+0

啊,我不明白他的意思。 – 2009-10-01 16:57:52

1

您的代码比您需要完成此任务更复杂。如果您知道小数点总是表示一个稳定值,无论该小数点两边的数字长度如何,您都很幸运。

1)然后,你必须仅仅多个原始的数目由100

2)如果(号码(x.charAt(INDEXOF( “”)+ 1))> 4){X + = 1},其中x是你的号码

3)parseInt函数

4)除以100,和你做。

+0

“如果您知道小数点将始终代表稳定值,而不管小数点两边的数字长度是多少。“ - 谨慎地阐述你的意思? – 2009-10-01 16:52:28

0

不,你说得对。

我测试了你的代码与ceil modifictaion,它的工作原理。

+0

ceil不起作用...使用ceil似乎会产生不准确的结果,例如:利息价格:£295.30 155英镑支付1.90英镑,之后支付0.81英镑。总计达295.31,其中一笔支付必须是0.80英镑...... – 2009-10-01 17:40:37

+1

@尼尔:因为你总是四舍五入,你总会得到一个总数大于精确值的总数。即使四舍五入你有时也会有所不同。如果您希望总额相同,您必须计算最终付款为总额与以前实际付款总额之间的差额。 – Guffa 2009-10-01 18:21:25

+0

@Guffa我理解这一点,如果你看看我在编辑中添加了什么,你会看到我正在尝试的实际公式......也许你可以看到需要应用这个公式才能工作的数字。 – 2009-10-01 18:24:27

1

替换Math.round()Math.ceil()应该工作:该错误必须在其他地方。

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

btw:使用带有货币值的浮点数学是一个坏主意:改用固定点算术!


现在我们知道你想做什么,这里的后者计算所需的值,你的例子代码:

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; 
+0

我已经添加了我试图找出的公式......任何想法? – 2009-10-01 17:58:55

1

建议使用定点运算是很好的建议。不幸的是,Javascript中没有定点算术 - 所有数字都是双精度浮点数。 (好吧,没有定点算法,没有拉入某些明确的支持库。)

对于文本字段中的输入输入,我已经开始处理数字作为字符串(尽可能)。将输入切换到小数点左侧和右侧的部分,然后使用整数值(必要时通过Math.floor())。如果你必须处理超过小数点后第二位的杂散数字,或者将它们当作错误(它们意味着什么?),否则,再次将它们分开并将它们作为整数处理。

如果你是而不是处理用户提供的值(即,来自文本输入字段的东西),那么你真的不应该在Javascript中这样做,因为再次,你没有数字你真正需要的工具。

+0

在JS中可能没有专门的定点算术,但你总是可以用适当的因子乘以所有的值来得到整数;数学将是准确的,只要你不耗尽双精度的双精度 – Christoph 2009-10-01 18:43:18