rounding in base 10

折月煮酒 提交于 2019-12-08 06:51:00

问题


I have a function to round a number given to the function to the nearest whole pence.

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

however it has come to my attention that the said number inputted into the function must only be rounded up to the nearest one pence however it must be rounded to two decimal places.

E.G.

15.236562213541684 would = 15.24  
9846.65456169846 would = 9846.66

I thought it would just be a case of changing return (Math.round(ac)/c); To return (Math.ceil(ac)/c);

Obviously I was very wrong.

Any help on this matter?

** EDIT **

Here is the formula that I'm trying to achieve maybe it'll help

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

so for example

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

can anyone right a function to do the above?

Here is a link to the current code i have including the formula... its a very old formula that I made when I first started JavaScript (which is a while ago now) however I'm still no better now as I was back then.

Can anyone clean it up to see if they can see why its not working to match the function above?


回答1:


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

I got it to give the results you want in this case. Not sure if it's going to work every time but it seems to. I'd definitely check it works as you want it to first.




回答2:


There's a built-in function for this already, Number.toFixed(numDigits), why not use this?

Parameter: digits
The number of digits to appear after the decimal point; this may be a value between 0 and 20, inclusive, and implementations may optionally support a larger range of values. If this argument is omitted, it is treated as 0.

Returns:
A string representation of number that does not use exponential notation and has exactly digits digits after the decimal place. The number is rounded if necessary, and the fractional part is padded with zeros if necessary so that it has the specified length. If number is greater than 1e+21, this method simply calls Number.toString() and returns a string in exponential notation.

Example:

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

This last one doesn't match your example - 9846.65456169846 rounded to two decimal places should be 9846.65, not 9846.66.




回答3:


Your code is more complex than what you need for this task. If you know the decimal point will always represent a stable value regardless of the length of digits on either side of that decimal point you are in luck.

1) Then you must merely multiple your original number by 100

2) if (Number(x.charAt(indexOF(".") + 1)) > 4) {x += 1} where x is your number

3) parseInt

4) divide by 100 and you are done.




回答4:


Advice to use fixed-point arithmetic is good advice. Unfortunately, there is no fixed-point arithmetic in Javascript - all numbers are double-precision floating-point numbers. (Well, no fixed-point arithmetic without pulling in some explicit support library.)

For scrubbing input in text fields, I've started dealing with the numbers as strings (to whatever extent possible). Chop the input up into the parts to the left and right of the decimal point, then work in integer values (via Math.floor() when necessary). If you've got to deal with stray digits past the 2nd decimal place, either treat them as an error (what do they mean anyway?) or else, again, split them off and work with them as integers.

If you're not dealing with user-supplied values (i.e., stuff from text input fields), then you really shouldn't be doing this in Javascript, because, again, you don't have the numeric tools you really need.




回答5:


Replacing Math.round() with Math.ceil() should work: The bug must be somewhere else.

Also, I suggest dropping the isNaN(parseInt()) completely as the math functions will cast to number anyway, returning NaN if that's not possible. This will lead to the function returning NaN as well, which is a better fit than boolean false.

And btw: it's a bad idea to use floating point math with monetary values: use fixed point arithmetics instead!


Now that we know what you're trying to do, here's the code which computes the desired values for your example:

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;

Changing round() to ceil() for all computations didn't work as the last payment has to be rounded normally to compensate the inaccuracies due to using floating point values.

It's generally better to only use integer math, so multiply all values with 100 and convert only when outputting the values:

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;



回答6:


No, you were right.

I tested your code with the ceil modifictaion, and it works.



来源:https://stackoverflow.com/questions/1505108/rounding-in-base-10

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!