By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,667 Members | 2,261 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,667 IT Pros & Developers. It's quick & easy.

Round off

P: n/a
Has anyone found a reliable way to force JS to round to a specific number of
places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?

Thanks

-S

Apr 4 '06 #1
Share this Question
Share on Google+
36 Replies


P: n/a
Phat G5 (G3) said the following on 4/4/2006 6:35 PM:
Has anyone found a reliable way to force JS to round to a specific number of
places?
Yes.
Every time I try I get different results.
Then you aren't doing it right.
For example, I'd need to round 3.4589 to 2 places.
Hmmm. I seem to recall something in the group FAQ about rounding to 2
places.
<URL: http://jibbering.com/faq/#FAQ4_6 >
What is the most reliable way to do it?


Most reliable? Post in Usenet and ask how to do it to have someone point
you to the FAQ of the group you post it to.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Apr 4 '06 #2

P: n/a
JRS: In article <C0*******************@noone.com>, dated Tue, 4 Apr
2006 15:35:52 remote, seen in news:comp.lang.javascript, Phat G5 (G3)
<no****@noone.com> posted :
Has anyone found a reliable way to force JS to round to a specific number of
places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?


By reading the newsgroup FAQ before posting, and finding, IIRC, section
4.6 therein.

Your "most reliable" is a pointless term; either a method is reliable
(perhaps within stated limits) or it is wrong.

Remember the "Banker's Rounding" question, and the limitations on which
exact values a Number can take.

Of course, if your 3.4589 is a String, a different approach should be
considered.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Apr 5 '06 #3

P: n/a

"Phat G5 (G3)" <no****@noone.com> wrote in message
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific number of places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?


Some folks find it satisfactory to:
multiply the number by 100, then round it , then divide that by 100.
Some folks rather hassle a person over a well-meant question -
or a well-meant answer - like this.
( here it comes, I'm sure)
Apr 6 '06 #4

P: n/a
Hal Rosser wrote:
"Phat G5 (G3)" [...] wrote [...]
Has anyone found a reliable way to force JS to round to a specific number
of places? Every time I try I get different results. For example, I'd
need to round 3.4589 to 2 places. What is the most reliable way to do it?


Some folks find it satisfactory to:
multiply the number by 100, then round it , then divide that by 100.
Some folks rather hassle a person over a well-meant question -
or a well-meant answer - like this.
( here it comes, I'm sure)


Your well-meant answer is simply bad advice. The FAQ (which is an acronym
for Frequently Asked Questions -- remember?) tells why, and understanding
how numeric values are stored in ECMAScript implementations, which we
discussed at great length and in great detail not too long ago, also does.

I got the impression that this newsgroup is dedicated to giving the best
advice possible, so do not be surprised if you get bashed when you post
(such) clueless nonsense.
PointedEars
Apr 6 '06 #5

P: n/a

"Hal Rosser" <hm******@bellsouth.net> wrote in message
news:_2************@bignews8.bellsouth.net...

"Phat G5 (G3)" <no****@noone.com> wrote in message
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific number
of
places? Every time I try I get different results. For example, I'd need

to round 3.4589 to 2 places. What is the most reliable way to do it?


Some folks find it satisfactory to:
multiply the number by 100, then round it , then divide that by 100.
Some folks rather hassle a person over a well-meant question -
or a well-meant answer - like this.
( here it comes, I'm sure)


I'm not sure - but it looks like someone is saying its incorrect to round to
2 decimals with code
like this;
var num = 3.4589; // ***( number to be rounded to 2 decimals)
num = num * 100; //*** (Multiply the number by 100) num is now 345.89
num = Math.round(num); //*** (Then round it) num is now 346
num = num/100; // *** (then divide that number by 100) num is now 3.46
-- but I have seen the exact code in text books used in many schools.
Why is my (well-meaning) answer wrong ?
or should OP jump through 20 hoops before getting a straight answer from a
couple of mean-spirited ego hounds who think this group is the ultimate
source for javascript.
**never-mind**
---OP --- do what they say


Apr 6 '06 #6

P: n/a
Hal Rosser said on 06/04/2006 12:09 PM AEST:
"Hal Rosser" <hm******@bellsouth.net> wrote in message
news:_2************@bignews8.bellsouth.net... [...]
Some folks find it satisfactory to:
multiply the number by 100, then round it , then divide that by 100.
Some folks rather hassle a person over a well-meant question -
or a well-meant answer - like this.
( here it comes, I'm sure)


The FAQ provides a solution and explanation of why other methods are
faulty, hence other posters referenced the FAQ rather than attempt to
parrot or paraphrase it.

I'm not sure - but it looks like someone is saying its incorrect to round to
2 decimals with code
like this;
Yes, they are.

var num = 3.4589; // ***( number to be rounded to 2 decimals)
num = num * 100; //*** (Multiply the number by 100) num is now 345.89
num = Math.round(num); //*** (Then round it) num is now 346
num = num/100; // *** (then divide that number by 100) num is now 3.46
-- but I have seen the exact code in text books used in many schools.
The fact that something is written in a book does not make it good
advice. Some would say that any advice found in some books is almost
certainly wrong. ;-)

Why is my (well-meaning) answer wrong ?
The reason why it is wrong is explained in the FAQ - your proposed
solution does not always give the right answer. The short answer is
because JavaScript numbers can't represent all decimal values exactly,
depending on them to do so will fail some of the time.

e.g.

12.024999999999999 -> 12.02 as expected
12.0249999999999999 -> 12.03 ?

or should OP jump through 20 hoops before getting a straight answer from a
couple of mean-spirited ego hounds who think this group is the ultimate
source for javascript.
**never-mind**
---OP --- do what they say


Read FAQ 4.6, it is rather concise but if studied it will all become
apparent. Also read 4.7, which helps to explain why the *100/100
method doesn't work consistently.

<URL:http://www.jibbering.com/FAQ/#FAQ4_6>
If you have any specific questions, ask. Do not mind that some
responses are curt or abrupt - such is life.

Search the archives for questions on rounding - you may be surprised by
totally unrelated gems you discover. :-)

Or use:

<URL:http://www.merlyn.demon.co.uk/js-round.htm>

--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>
Apr 6 '06 #7

P: n/a
// Roundoff routine for 2 decimal places
// used someplaces.

function round(x) {
return Math.round(x*100)/100;
}

Been using it for years in my raceway fill calculator at
http://www.electrician2.com/
And never had a complaint.

Apr 6 '06 #8

P: n/a
<If you have any specific questions, ask. Do not mind that some
responses are curt or abrupt - such is life.
Search the archives for questions on rounding - you may be surprised by

totally unrelated gems you discover. :-) >

You are so anal your head is coming out of your ass. Just thought I
would let you know before you are seen in public.

Apr 6 '06 #9

P: n/a
el*********@electrician.com said on 06/04/2006 2:09 PM AEST:
<If you have any specific questions, ask. Do not mind that some
responses are curt or abrupt - such is life.
Search the archives for questions on rounding - you may be surprised by

totally unrelated gems you discover. :-) >

You are so anal your head is coming out of your ass. Just thought I
would let you know before you are seen in public.


You're a very funny fellow. :-p

Funniest thing is not only don't you understand why you are wrong, but
you refuse to learn. You've posted incorrect responses before and had
the errors pointed out to you, yet you persist in offering bad advice.

Troll-on.
--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>
Apr 6 '06 #10

P: n/a
el*********@electrician.com said on 06/04/2006 2:05 PM AEST:
// Roundoff routine for 2 decimal places
// used someplaces.

function round(x) {
return Math.round(x*100)/100;
}

Been using it for years in my raceway fill calculator at
http://www.electrician2.com/
And never had a complaint.


Ah, so that's why you include the comment:

// Code roundoff method may not be consistant!
// There may be other hairline problems not found yet!!

Care to explain to the OP why you figure it's not worth pointing out
that you don't know the limitations of the function you propose?

The only way anyone is going to complain about your calculator is if
they fully test it to discover the errors or it causes a catastrophic
failure.

Given the complexity of doing so, it is unlikely anyone will attempt the
former, they trust you to have done it. And given the nature of most
electrical products, there is sufficient safety margin to prevent the
second provided your errors don't encroach too far.

But that does not make your rounding algorithm a good solution,
particularly when its shortcomings, and a simple and reliable
alternative, have been pointed out to you.
--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>
Apr 6 '06 #11

P: n/a
> Read FAQ 4.6, it is rather concise but if studied it will all become
apparent. Also read 4.7, which helps to explain why the *100/100
method doesn't work consistently.

<URL:http://www.jibbering.com/FAQ/#FAQ4_6>
If you have any specific questions, ask. Do not mind that some
responses are curt or abrupt - such is life.


Ok, I read that FAQ 4.6
The code in that section is a marvelous display of someone's mastery of
javascript. I applaud the author.
The code, however, is missing comments (documentation) explaining what the
code is doing, and what the args represent. Someone looking for help (ie: a
beginner - or a programmer of lesser experience in javascript- like myself)
would likely come away from FAQ 4.2 with a sense of confusion. You have to
admit, someone else's undocumented code is sometimes difficult to follow.
I also followed the first link listed in FAQ 4.2 to look for clearer
explanations on the art of rounding a number like 3.4589 to 2 decimals.
Then I followed the link (in FAQ 4.2) to a section of that page (General
Rounding section) and guess what!!! -
Look at the 3rd example in the "General Rounding" section of that link:
http://www.merlyn.demon.co.uk/js-round.htm#Gen
It sure looks like they multiplied by 100, then rounded it, then divided by
100 - doesn't it?
The circle is complete, and the wild goose we were sent to chasing suddenly
vanishes.
w3schools.com and devguru.com are not entirely without merit after all.


Apr 6 '06 #12

P: n/a
Hal Rosser said on 06/04/2006 2:53 PM AEST:
Read FAQ 4.6, it is rather concise but if studied it will all become
apparent. Also read 4.7, which helps to explain why the *100/100
method doesn't work consistently.

<URL:http://www.jibbering.com/FAQ/#FAQ4_6>
If you have any specific questions, ask. Do not mind that some
responses are curt or abrupt - such is life.

Ok, I read that FAQ 4.6
The code in that section is a marvelous display of someone's mastery of
javascript. I applaud the author.
The code, however, is missing comments (documentation) explaining what the
code is doing, and what the args represent. Someone looking for help (ie: a
beginner - or a programmer of lesser experience in javascript- like myself)
would likely come away from FAQ 4.2 with a sense of confusion. You have to
admit, someone else's undocumented code is sometimes difficult to follow.


Yes, completely, both in general and this particular case.

I also followed the first link listed in FAQ 4.2 to look for clearer
explanations on the art of rounding a number like 3.4589 to 2 decimals.
Then I followed the link (in FAQ 4.2) to a section of that page (General
Rounding section) and guess what!!! -
Look at the 3rd example in the "General Rounding" section of that link:
http://www.merlyn.demon.co.uk/js-round.htm#Gen
It sure looks like they multiplied by 100, then rounded it, then divided by
100 - doesn't it?
Yes, but the preceding text notes that[1]:

Math.round(1.035*100)/100 gives 1.03
but Math.round(2.035*100)/100 gives 2.04
Hopefully my formatting makes the error obvious.

This may seem trivial, however originally the difference between the two
numbers was 1.00, now it's 1.01. Depending on how that is used, a test
may pass or fail that should not have.

The circle is complete, and the wild goose we were sent to chasing suddenly
vanishes.
w3schools.com and devguru.com are not entirely without merit after all.


I do not like DevGuru at all, avoid it. I am less inclined to recommend
w3schools each time I visit. Both sites claim to be more than they are,
they are misleading their audience if they propose a flawed method of
rounding and do not point out the errors. What other errors are waiting
to be discovered? These sites are targeted at novices who know no
better, yet teach bad habits and fautly algorithms.

I understand criticism of JRS's coding style, IMHO it is unreasonably
concise, particularly when it is aimed at education. But for all his
faults, he is nearly always factually correct in regard to the topics
discussed at www.merlyn.demon.co.uk/js*.

1. To JRS, if lurking, note the addition of '/100' in the quoted text.

--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>
Apr 6 '06 #13

P: n/a

"Phat G5 (G3)" <no****@noone.com> schrieb im Newsbeitrag
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific
number of
places? Every time I try I get different results. For example, I'd
need to
round 3.4589 to 2 places. What is the most reliable way to do it?


Document.Write(Round(3.4589, 2));
function Round(number, places)
{
places = Math.exp(10, places);
return Math.floor((number+.5) * places) / places;
}

Not tested, but should work.
Apr 6 '06 #14

P: n/a
Zif
Gernot Frisch wrote:
"Phat G5 (G3)" <no****@noone.com> schrieb im Newsbeitrag
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific
number of
places? Every time I try I get different results. For example, I'd
need to
round 3.4589 to 2 places. What is the most reliable way to do it?

Document.Write(Round(3.4589, 2));


Is that supposed to be document.write()?
function Round(number, places)
{
places = Math.exp(10, places);
Math.exp(x) takes one argument, not two. The second argument will be
ignored. You are setting places to the value of Math.exp(10) -
approximately 22026.465794806718. Always.

return Math.floor((number+.5) * places) / places;
Here you arbitrarily add 0.5, multiply by a constant (22026.465794806718),
'floor' the result, then divide by the same constant. How is that going to
guarantee a reliable rounding function?

}

Not tested, but should work.


Had you tested it you'd find that it doesn't 'work'. Given 3.4589, your
Round function returns 3.958873875288679.

Is that any use what so ever to the OP?
--
Zif
Apr 6 '06 #15

P: n/a
"Gernot Frisch" <Me@Privacy.net> writes:

[round to two places]
Document.Write(Round(3.4589, 2));
function Round(number, places)
{
places = Math.exp(10, places);
should be:
places = Math.pow(10, places)
(for readability reasons, I would create a new variable instead
of reusing the parameter).
return Math.floor((number+.5) * places) / places;
The .5 should be just before flooring, so:

return Math.floor((number * places) + 0.5) / places;
Not tested, but should work.


No better than
return Math.round(number * places)/places;
which has been debunked elsewhere in the thread.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Apr 6 '06 #16

P: n/a
JRS: In article <_2************@bignews8.bellsouth.net>, dated Wed, 5
Apr 2006 21:25:28 remote, seen in news:comp.lang.javascript, Hal Rosser
<hm******@bellsouth.net> posted :

"Phat G5 (G3)" <no****@noone.com> wrote in message
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific number

of
places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?


Some folks find it satisfactory to:
multiply the number by 100, then round it , then divide that by 100.
Some folks rather hassle a person over a well-meant question -
or a well-meant answer - like this.
( here it comes, I'm sure)


Perhaps you could ask your mathematics teachers about the conceptual
difference between rounding to a multiple of 0.01 giving a Number, and
rounding to two decimal places which necessarily gives a String.

===========

In my system, somewhat to my surprise, Math.pow(10, N) is faster than
Number("1e"+N), and is sufficiently accurate[*] ; unless I hear that the
contrary is generally true, I'll change my pages.
[*] for (j=0; j<40; j++) document.writeln(j, " ", +("1E"+j), " ",
t=Math.pow(10, j), " ", t%1, "<br>")
My results for 23 & 29 need some more thought.

FAQ 4.6 can be correspondingly changed.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Apr 6 '06 #17

P: n/a

"Dr John Stockton" <jr*@merlyn.demon.co.uk> wrote in message
news:CS**************@merlyn.demon.co.uk...
JRS: In article <_2************@bignews8.bellsouth.net>, dated Wed, 5
Perhaps you could ask your mathematics teachers about the conceptual
difference between rounding to a multiple of 0.01 giving a Number, and
rounding to two decimal places which necessarily gives a String.
******
The OP asked about rounding a number to 2 decimals - not about converting it
to a string.
***
===========

In my system, somewhat to my surprise, Math.pow(10, N) is faster than
Number("1e"+N), and is sufficiently accurate[*] ; unless I hear that the
contrary is generally true, I'll change my pages.

[*] for (j=0; j<40; j++) document.writeln(j, " ", +("1E"+j), " ",
t=Math.pow(10, j), " ", t%1, "<br>")
My results for 23 & 29 need some more thought.

FAQ 4.6 can be correspondingly changed.


I'm sure that code is very clever and correct.
It is, however just so mush gibberish to someone who's trying to learn
something.
The code has no comments (documentation) to explain what the args represent
or what the code is doing, or which function is to be called or in what
manner or what order.
It would be nice if someone would take a look at the FAQs and add comments
where they would help a newbie.
The FAQs now appears to be a place where people who already know javascript
are showing off their proficiency in the language to each other.
This is meant to be constructive, so I hope its taken as such.
Apr 7 '06 #18

P: n/a
Hal Rosser said the following on 4/6/2006 10:59 PM:
"Dr John Stockton" <jr*@merlyn.demon.co.uk> wrote in message
news:CS**************@merlyn.demon.co.uk...
JRS: In article <_2************@bignews8.bellsouth.net>, dated Wed, 5
Perhaps you could ask your mathematics teachers about the conceptual
difference between rounding to a multiple of 0.01 giving a Number, and
rounding to two decimal places which necessarily gives a String.
******
The OP asked about rounding a number to 2 decimals - not about converting it
to a string.
***


And the best, reliable, method of rounding a number to 2 decimal places
is done by converting that number to a string and then doing string
manipulation.
===========

In my system, somewhat to my surprise, Math.pow(10, N) is faster than
Number("1e"+N), and is sufficiently accurate[*] ; unless I hear that the
contrary is generally true, I'll change my pages.

[*] for (j=0; j<40; j++) document.writeln(j, " ", +("1E"+j), " ",
t=Math.pow(10, j), " ", t%1, "<br>")
My results for 23 & 29 need some more thought.

FAQ 4.6 can be correspondingly changed.


I'm sure that code is very clever and correct.


It's irrelevant actually to the question at hand.
It is, however just so mush gibberish to someone who's trying to learn
something.
Most of John's code appears to be gibberish even to those that
understand it.
The code has no comments (documentation) to explain what the args represent
or what the code is doing, or which function is to be called or in what
manner or what order.
It would be nice if someone would take a look at the FAQs and add comments
where they would help a newbie.
Very true. It doesn't do a lot of good to say "Read the FAQ" if the FAQ
is not written with the novice/newbe in mind.
The FAQs now appears to be a place where people who already know javascript
are showing off their proficiency in the language to each other.


Not true.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Apr 7 '06 #19

P: n/a
In article <2x**************@bignews8.bellsouth.net>, Hal Rosser
<hm******@bellsouth.net> writes

<snip>
******
The OP asked about rounding a number to 2 decimals - not about converting it
to a string.
***

<snip>

The most reliable way to do decimal rounding is to operate on the
decimal representation of the number. In javascript this means you have
to start by translating the internal binary representation into a
string. (At present. Microsoft wanted numbers to be decimal-coded. I
don't know if they still do.)

This is probably what JohnS meant. Then again, perhaps not. It's not
always easy to work out what he means when he's operating in sarcastic
teacher mode.

Actually, the OP didn't say if he wants decimal rounding, or hexadecimal
rounding, or duodecimal rounding, or ternary rounding, or binary
rounding to two places. We are all guessing he meant decimal as that's
what most people want to display to their end users.

John
--
John Harris
Apr 7 '06 #20

P: n/a
JRS: In article <2x**************@bignews8.bellsouth.net>, dated Thu, 6
Apr 2006 22:59:22 remote, seen in news:comp.lang.javascript, Hal Rosser
<hm******@bellsouth.net> posted :

"Dr John Stockton" <jr*@merlyn.demon.co.uk> wrote in message
news:CS**************@merlyn.demon.co.uk...
JRS: In article <_2************@bignews8.bellsouth.net>, dated Wed, 5
Perhaps you could ask your mathematics teachers about the conceptual
difference between rounding to a multiple of 0.01 giving a Number, and
rounding to two decimal places which necessarily gives a String.

******
The OP asked about rounding a number to 2 decimals - not about converting it
to a string.
***


"Two decimal places" implies a string. Number 3.5 is a multiple of
0.01, but it has only one decimal place. String "3.50" represents a
multiple of 0.01, and has two decimal places. They have the same
numerical value.

===========

In my system, somewhat to my surprise, Math.pow(10, N) is faster than
Number("1e"+N), and is sufficiently accurate[*] ; unless I hear that the
contrary is generally true, I'll change my pages.

[*] for (j=0; j<40; j++) document.writeln(j, " ", +("1E"+j), " ",
t=Math.pow(10, j), " ", t%1, "<br>")
My results for 23 & 29 need some more thought.

FAQ 4.6 can be correspondingly changed.


I'm sure that code is very clever and correct.
It is, however just so mush gibberish to someone who's trying to learn
something.


Don't quote what you're not commenting on. It confuses and annoys your
readers.

The FAQ author evidently did not feel that the comment presented in and
for StrU and its friends in js-round.htm needed to be repeated in the
FAQ, given that he was providing a link to js-round.htm. There, StrU
currently starts
function StrU(X, M, N) { // X>=0.0 ; gives M digits point N digits

Remember that the FAQ is posted twice a week, and that some users will
be on dial-up or wireless links. That is why (IMHO) the FAQ rightly
gives brief answers with links to further information.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME
Web <URL:http://www.uwasa.fi/~ts/http/tsfaq.html> -> Timo Salmi: Usenet Q&A.
Web <URL:http://www.merlyn.demon.co.uk/news-use.htm> : about usage of News.
No Encoding. Quotes before replies. Snip well. Write clearly. Don't Mail News.
Apr 7 '06 #21

P: n/a
> >The OP asked about rounding a number to 2 decimals

got a method i want you to judge for reliability, might work but i have
a feeling its not as reliable as the way in the faq.

the Math.round trick gives 1.03 and 2.04 when you put in 1.035 and
2.035 but what if you carry on incrementing the number until the same
numbers after the decimal point appear a few times in a row.

using the math.round thingie in a loop and repeating until a consistent
answer is found seems to work where math.round on its own doesnt work
but have i missed some other math errors?

methinks its ok for just a few decimal places but more than that and it
is unreliable

the line with all the math.round calls just does the same as Math.round
in earlier examples but it does it so the result is between 0 and 1 for
the comparison.

function around( num, places ) {
i=0;
sign = (num >= 0) ? +1 : -1;
prev = Array(-1,-2,-1);
scale = Math.pow(10,places);
while( prev[0] != prev[1] || prev[1] != prev[2] )
prev[ Math.abs(++i) % 3 ] = ( Math.round( scale * (num +
sign*i) ) - ( Math.round(num + sign * i) * scale ) ) / scale;

return (Math.floor(Math.abs(num))*sign) + "." +
Math.abs(prev[0]).toString().substr(2,places);
}

ta all

joe

Apr 8 '06 #22

P: n/a

"Phat G5 (G3)" <no****@noone.com> wrote in message
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific number of places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?

Thanks


Found it!
Adding several zeroes after the decimal makes it behave.
Tested on over 300 combinations of random numbers and places..
Assumes you round UP anything >=5 and that -90.075 < -90.07
Let me know if you break it - and how.
I'm still refining this function.
*** The code ***
//the args: nnn = number to be rounded
// yyy = number of places
function roundy(nnn,yyy){
multy = Math.pow(10,yyy); // ** the multiplier to use
nnn+=""; //** coerce nnn to a String
//make sure there's a dot and something after it
if (nnn.indexOf(".") < 0){
nnn += ".0";
}
//** adding zeroes after the dot makes it behave
nnn += "00000";
nnn *=1; //** coerce it back to a number
//** now multiply by 10^yyy, round it, then divide by 10^yyy -
works!
return Math.round(nnn * multy) / multy;
}
Apr 8 '06 #23

P: n/a
>
function around( num, places ) {
i=0;
sign = (num >= 0) ? +1 : -1;
prev = Array(-1,-2,-1);
scale = Math.pow(10,places);
while( prev[0] != prev[1] || prev[1] != prev[2] )
prev[ Math.abs(++i) % 3 ] = ( Math.round( scale * (num +
sign*i) ) - ( Math.round(num + sign * i) * scale ) ) / scale;

return (Math.floor(Math.abs(num))*sign) + "." +
Math.abs(prev[0]).toString().substr(2,places);
}

ta all

joe


Hi Joe,
I tested your function with a few numbers that they tested mine with.
Your code seems to crash (or go into an endless loop) with negative numbers.
and these runs give these results:
around (0.0, 2) returns .01
around (11.34, 5) returns 11.351
around( -90.07, 2) *** crashed ** (I think an infinite loop)
.... The other tests did ok . I used Firefox.
Hope this helps
I think I've come upon an answer, also. see previous posts.
Apr 9 '06 #24

P: n/a
JRS: In article <ug****************@bignews2.bellsouth.net>, dated Sat,
8 Apr 2006 16:47:32 remote, seen in news:comp.lang.javascript, Hal
Rosser <hm******@bellsouth.net> posted :

Let me know if you break it - and how.


Your *first* problem is that you have not yet understood what rounding
to two decimal places actually means. It is not equivalent to rounding
a number to a multiple of 0.01. The result *must* be a String.

Before attempting to offer code here as an answer to a specific question
or for general use, you should *read* and *understand* the newsgroup
FAQ.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Apr 9 '06 #25

P: n/a
"Phat G5 (G3)" <no****@noone.com> wrote in message
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific number of places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?

Thanks

-S

Dear OP,
The *** insists on returning a String, so here's an understandable piece
of code that will do just that(unlike FAQ 4.6 which is not understandable).
I will persist to resist FAQ 4.6 against all odds because of the unneeded
complexity of that code. I mean *really* look at it.

// args->nnn is the number to round,
// and yyy the number of places
function roundyv2(nnn,yyy){
multy = Math.pow(10,yyy); //** the multiplier to use
nnn+=""; //** coerce nnn to a String
//make sure there's a dot and something after it
if (nnn.indexOf(".") < 0){
nnn += ".0";
}
//** adding zeroes after the dot makes it behave
nnn += "00000";
nnn *=1; //** coerce it back to a number
//** now rounding works ***
var strOut = Math.round(nnn * multy) / multy;
//return strOut;//would return a number here
strOut = "" + strOut;//**coerce to String
var places = strOut.length - strOut.indexOf(".") - 1;
var zeroesNeeded = yyy - places;
var strZeroes = Math.pow(10, zeroesNeeded) + "";
if (zeroesNeeded > 0) {
strOut += strZeroes.substr(1);
}
return strOut;
}
Apr 9 '06 #26

P: n/a

"Phat G5 (G3)" <no****@noone.com> wrote in message
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific number of places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?

Thanks

-S

but in the latest Firefox, this works ok:
return 3.4589.toFixed(2);
Apr 9 '06 #27

P: n/a
JRS: In article <UV****************@bignews5.bellsouth.net>, dated Sun,
9 Apr 2006 15:08:45 remote, seen in news:comp.lang.javascript, Hal
Rosser <hm******@bellsouth.net> posted :
The *** insists on returning a String, so here's an understandable piece
of code that will do just that(unlike FAQ 4.6 which is not understandable).
FAQ 4.6 deals with cases that your code does not attempt to deal with;
so you may not see the need for some of it.

Your code provides no way to choose the representation of the sign; 4.6
does, by modifying Sign.

The code in the FAQ provides a routine, Stretch, potentially useful
elsewhere. If it's not used elsewhere, that part of the job can easily
be done within StrU.

The code in the FAQ adds leading zeroes if required.

The code in the FAQ also shows how to implement a .toFixed for Number.

By the way, although I used to use the code in the FAQ, I now use code
developed from it.

I will persist to resist FAQ 4.6 against all odds because of the unneeded
complexity of that code. I mean *really* look at it.

// args->nnn is the number to round,
// and yyy the number of places
function roundyv2(nnn,yyy){
multy = Math.pow(10,yyy); //** the multiplier to use // nnn+=""; //** coerce nnn to a String
//make sure there's a dot and something after it
if (nnn.indexOf(".") < 0){
nnn += ".0";
}
//** adding zeroes after the dot makes it behave
nnn += "00000";
nnn *=1; //** coerce it back to a number
//** now rounding works *** // var strOut = Math.round(nnn * multy) / multy;
//return strOut;//would return a number here
strOut = "" + strOut;//**coerce to String
var places = strOut.length - strOut.indexOf(".") - 1;
var zeroesNeeded = yyy - places;
var strZeroes = Math.pow(10, zeroesNeeded) + "";
if (zeroesNeeded > 0) {
strOut += strZeroes.substr(1);
}
return strOut;
}


If the input nnn is a small integer, your code extends it, changing its
value. Try, for example, roundyv2(1, 2), which gives "10".

For what conditions do you think that your lines between my added //
marks actually do something useful, and what do they then achieve?

Is using Math.pow an *efficient* way of generating trailing zeroes, in
comparison with others, averaged over probable usage?

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Apr 10 '06 #28

P: n/a
JRS: In article <1Z****************@bignews5.bellsouth.net>, dated Sun,
9 Apr 2006 15:12:05 remote, seen in news:comp.lang.javascript, Hal
Rosser <hm******@bellsouth.net> posted :
"Phat G5 (G3)" <no****@noone.com> wrote in message
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific numberof
places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?

but in the latest Firefox, this works ok:
return 3.4589.toFixed(2);

Phat G5 (G3) wants a *reliable* way.

On the World-Wide Web, one cannot reliably assume that the end user has
the latest Firefox.

In at least one version of at least one popular browser, the native
toFixed is known to give correct results in some cases.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Apr 10 '06 #29

P: n/a
> "RobG" <rg***@iinet.net.au> wrote:
news:zD******************@news.optus.net.au....
[snip]

Read FAQ 4.6, it is rather concise but if studied it will all become
apparent. Also read 4.7, which helps to explain why the *100/100
method doesn't work consistently.

<URL:http://www.jibbering.com/FAQ/#FAQ4_6>

[snip]

0 - 100 test numbers, 3 decimals rounded to 2

May I be missing something? The script posted in FAQ4_6 seems to
generate 572 Anomalies.
http://files.photojerk.com/BootNic/Anomalies.png

IE6 toFixed 5 Anomalies
Mozilla 1.7.12 toFixed 4800 Anomalies
Opera 8.54 toFixed 5000 Anomalies

While the native toFixed results surprise me only by the fact that IE6 only
returned 5 Anomalies.

What would be a good way to test the results of a script like this?

--
BootNic Monday, April 10, 2006 2:54 PM

People grow through experience if they meet life honestly and
courageously. This is how character is built.
*Eleanor Roosevelt*

Apr 10 '06 #30

P: n/a

"Phat G5 (G3)" <no****@noone.com> wrote in message
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific number of places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?

Thanks

-S


** Here's latest version thanks to John's code-testing services
** removed some superfluous code and fixed the 1-digit bug

//**args ->nnn = the number to round and yyy= the number of places
function roundyv3(nnn,yyy){
//** the multiplier to use
var multy = "1e"+yyy;//*same as Math.pow(10, yyy) ***
nnn+=""; //** coerce nnn to a String
//make sure there's a dot and something after it
if (nnn.indexOf(".") < 0){
nnn += ".0";
}
//** adding zeroes after the dot makes it behave when rounding
nnn = nnn + "00000";
//** now rounding works - but removes the dot if a whole number ***
var strOut = String(Math.round(nnn * multy) / multy);
//add back the decimal if rounding removed it and yyy > 0
if (strOut.indexOf(".") < 0 && yyy > 0) {
strOut+= ".0";
}
var placesInStrOut = strOut.length - strOut.indexOf(".") - 1;
var zeroesNeeded = yyy - placesInStrOut;
var strZeroes = String(Math.pow(10, zeroesNeeded));
if (zeroesNeeded > 0) {
strOut += strZeroes.substr(1);
}
return strOut;
}
Apr 11 '06 #31

P: n/a

"Dr John Stockton" <jr*@merlyn.demon.co.uk> wrote in message
news:EQ**************@merlyn.demon.co.uk...
JRS: In article <UV****************@bignews5.bellsouth.net>, dated Sun,
9 Apr 2006 15:08:45 remote, seen in news:comp.lang.javascript, Hal
Rosser <hm******@bellsouth.net> posted :
FAQ 4.6 deals with cases that your code does not attempt to deal with;
so you may not see the need for some of it. ***
OK... right - but its not documented and its confusing code
Your code provides no way to choose the representation of the sign; 4.6
does, by modifying Sign. ***
Don't see a need for it negatives have a minus sign, (You want to add
parentheses, or what, for negatives?)
The code in the FAQ provides a routine, Stretch, potentially useful
elsewhere. If it's not used elsewhere, that part of the job can easily
be done within StrU. *******
but it is uncommented ,obfuscated code
You blasted my code (in a previous post) for not indenting-- but look at the
code in FAQ4.6 hehe
The code in the FAQ adds leading zeroes if required. ***
(For rounding backwards ??) (When would that be required?)
The code in the FAQ also shows how to implement a .toFixed for Number. **
I disagree - it confuses the reader unless he doesn't need to read the FAQ
**
By the way, although I used to use the code in the FAQ, I now use code
developed from it. ***
I would be interested in seeing *documented* code you're now using.
****
If the input nnn is a small integer, your code extends it, changing its
value. Try, for example, roundyv2(1, 2), which gives "10". ***
Fixed that - good catch - I forgot to reinsert the dot after rounding (whole
numbers).
For what conditions do you think that your lines between my added //
marks actually do something useful, and what do they then achieve? ***
Removed that - another decent (and constructive) catch - thanks.
Is using Math.pow an *efficient* way of generating trailing zeroes, in
comparison with others, averaged over probable usage?

***
The second hand on my clock didn't move much when that code executed, but I
changed one instance to the "1e" + x method. Purity of code is a good cause
I guess though.

I fixed it and reposted. Thanks for testing.
I took a 'software testing' course - but you have a real knack for it.
Hal
Apr 11 '06 #32

P: n/a
In article <h%*****************@bignews6.bellsouth.net>, Hal Rosser
<hm******@bellsouth.net> writes

<snip>
** Here's latest version thanks to John's code-testing services
** removed some superfluous code and fixed the 1-digit bug

//**args ->nnn = the number to round and yyy= the number of places
function roundyv3(nnn,yyy)
/* Preconditions :
abs(nnn) < 2^52 or thereabouts (you don't test for 'e' or 'E')
abs(yyy) < 20 or so (any more is pointless)
*/
{
//** the multiplier to use
var multy = "1e"+yyy;//*same as Math.pow(10, yyy) ***
nnn+=""; //** coerce nnn to a String
//make sure there's a dot and something after it
if (nnn.indexOf(".") < 0){
nnn += ".0";
}
//** adding zeroes after the dot makes it behave when rounding
nnn = nnn + "00000";
//** now rounding works - but removes the dot if a whole number ***
I don't see why you converted nnn into a string when the next thing you
do is convert it back into the original number.
var strOut = String(Math.round(nnn * multy) / multy);
//add back the decimal if rounding removed it and yyy > 0
if (strOut.indexOf(".") < 0 && yyy > 0) {
strOut+= ".0";
}
var placesInStrOut = strOut.length - strOut.indexOf(".") - 1;
var zeroesNeeded = yyy - placesInStrOut;
var strZeroes = String(Math.pow(10, zeroesNeeded));
if (zeroesNeeded > 0) {
strOut += strZeroes.substr(1);
}
return strOut;
}


John
--
John Harris
Apr 11 '06 #33

P: n/a

"John G Harris" <jo**@nospam.demon.co.uk> wrote in message
news:Z4**************@jgharris.demon.co.uk...
In article <h%*****************@bignews6.bellsouth.net>, Hal Rosser
<hm******@bellsouth.net> writes

<snip>
** Here's latest version thanks to John's code-testing services
** removed some superfluous code and fixed the 1-digit bug

//**args ->nnn = the number to round and yyy= the number of places
function roundyv3(nnn,yyy)
/* Preconditions :
abs(nnn) < 2^52 or thereabouts (you don't test for 'e' or 'E')
abs(yyy) < 20 or so (any more is pointless)
*/

-----ok---
{
//** the multiplier to use
var multy = "1e"+yyy;//*same as Math.pow(10, yyy) ***
nnn+=""; //** coerce nnn to a String
//make sure there's a dot and something after it
if (nnn.indexOf(".") < 0){
nnn += ".0";
}
//** adding zeroes after the dot makes it behave when rounding
nnn = nnn + "00000";
//** now rounding works - but removes the dot if a whole number ***
I don't see why you converted nnn into a string when the next thing you
do is convert it back into the original number.
****************************

*** to make sure a decimal point and zeroes are there
*** else rounding is inconsistent**************************
var strOut = String(Math.round(nnn * multy) / multy);
//add back the decimal if rounding removed it and yyy > 0
if (strOut.indexOf(".") < 0 && yyy > 0) {
strOut+= ".0";
}
var placesInStrOut = strOut.length - strOut.indexOf(".") - 1;
var zeroesNeeded = yyy - placesInStrOut;
var strZeroes = String(Math.pow(10, zeroesNeeded));
if (zeroesNeeded > 0) {
strOut += strZeroes.substr(1);
}
return strOut;
}


John
--
John Harris

Apr 11 '06 #34

P: n/a
JRS: In article <h%*****************@bignews6.bellsouth.net>, dated
Tue, 11 Apr 2006 00:14:15 remote, seen in news:comp.lang.javascript, Hal
Rosser <hm******@bellsouth.net> posted :

"Phat G5 (G3)" <no****@noone.com> wrote in message
news:C05842D8.33E67%no****@noone.com...
Has anyone found a reliable way to force JS to round to a specific numberof
places? Every time I try I get different results. For example, I'd need to
round 3.4589 to 2 places. What is the most reliable way to do it?

Thanks

-S


** Here's latest version thanks to John's code-testing services
** removed some superfluous code and fixed the 1-digit bug

//**args ->nnn = the number to round and yyy= the number of places
function roundyv3(nnn,yyy){


BTW, it's a good convention IMHO to use, as in Fortran, names such as X
for floats and such as N for integers. Javascript does not make the
distinction, but it can help readability.
//** the multiplier to use
var multy = "1e"+yyy;//*same as Math.pow(10, yyy) ***
But "1e"+yyy gives a String; Math.pow(10, yyy) gives a Number.
nnn+=""; //** coerce nnn to a String
//make sure there's a dot and something after it
if (nnn.indexOf(".") < 0){
nnn += ".0";
}
//** adding zeroes after the dot makes it behave when rounding
nnn = nnn + "00000";
When is that part beneficial, and how?
//** now rounding works - but removes the dot if a whole number ***
var strOut = String(Math.round(nnn * multy) / multy);
//add back the decimal if rounding removed it and yyy > 0
if (strOut.indexOf(".") < 0 && yyy > 0) {
strOut+= ".0";
}
var placesInStrOut = strOut.length - strOut.indexOf(".") - 1;
var zeroesNeeded = yyy - placesInStrOut;
var strZeroes = String(Math.pow(10, zeroesNeeded));
Why do that if zeroesNeeded is zero ? Also, it seems slower than using
a string constant of ten or twenty zeroes with substr.
if (zeroesNeeded > 0) {
strOut += strZeroes.substr(1);
}
return strOut;
}


Your code gives funny results with large numbers and NaN .
Your code rounds 3.965 to 3.97 but -3.965 to -3.96 .

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Apr 11 '06 #35

P: n/a
JRS: In article <Z4**************@jgharris.demon.co.uk>, dated Tue, 11
Apr 2006 21:16:17 remote, seen in news:comp.lang.javascript, John G
Harris <jo**@nospam.demon.co.uk> posted :
In article <h%*****************@bignews6.bellsouth.net>, Hal Rosser
<hm******@bellsouth.net> writes

<snip>
** Here's latest version thanks to John's code-testing services
** removed some superfluous code and fixed the 1-digit bug

//**args ->nnn = the number to round and yyy= the number of places
function roundyv3(nnn,yyy)


/* Preconditions :
abs(nnn) < 2^52 or thereabouts (you don't test for 'e' or 'E')
abs(yyy) < 20 or so (any more is pointless)
*/


You mean, I think, 2^53, the first integer that cannot be incremented
with ++. But the default conversion from Number to String does not use
e-format below almost 10^21.

Neither FAQ 4.6 nor my current code test for e/E as such; though they
detect them.

***

To use Bankers' Rounding sensibly, either it should be rounding to
integer (so x.5 is exact) or one should first round by a modest multiple
of the expected rounding error to an exact base-10 value (implying to a
string) and then do Bankers' on that.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Apr 12 '06 #36

P: n/a
In article <sW**************@merlyn.demon.co.uk>, Dr John Stockton
<jr*@merlyn.demon.co.uk> writes
JRS: In article <Z4**************@jgharris.demon.co.uk>, dated Tue, 11
Apr 2006 21:16:17 remote, seen in news:comp.lang.javascript, John G
Harris <jo**@nospam.demon.co.uk> posted :
In article <h%*****************@bignews6.bellsouth.net>, Hal Rosser
<hm******@bellsouth.net> writes

<snip>
** Here's latest version thanks to John's code-testing services
** removed some superfluous code and fixed the 1-digit bug

//**args ->nnn = the number to round and yyy= the number of places
function roundyv3(nnn,yyy)


/* Preconditions :
abs(nnn) < 2^52 or thereabouts (you don't test for 'e' or 'E')
abs(yyy) < 20 or so (any more is pointless)
*/


You mean, I think, 2^53, the first integer that cannot be incremented
with ++. But the default conversion from Number to String does not use
e-format below almost 10^21.

<snip>

Displaying something.75 when there are only 2 bits to the right of the
binary point would be thoroughly misleading. Displaying something.00
when there are no bits to the right of the binary point is also
misleading.

Deciding what should be written in the pre-conditions is not easy in
this case. My "thereabouts" had a much larger range than you might have
thought.

John
--
John Harris
Apr 14 '06 #37

This discussion thread is closed

Replies have been disabled for this discussion.