# FAQ Topic - How do I convert a Number into a String with exactly 2 decimal places?

Discussion in 'Javascript' started by FAQ server, Dec 13, 2006.

1. ### FAQ serverGuest

-----------------------------------------------------------------------
FAQ Topic - How do I convert a Number into a String with exactly 2 decimal places?
-----------------------------------------------------------------------

When formatting money for example, to format 6.57634 to
6.58, 6.5 to 6.50, and 6 to 6.00?

Rounding of x.xx5 is uncertain, as such numbers are not
represented exactly.

N = Math.round(N*100)/100 only converts N to a Number of value
close to a multiple of 0.01; but document.write(N) does not give
trailing zeroes.

ECMAScript Ed. 3.0 (JScript 5.5 [but buggy] and JavaScript 1.5)
introduced N.toFixed, the main problem with this is the bugs in
JScripts implementation.

Most implementations fail with certain numbers, for example 0.07.
The following works successfully for M>0, N>0:

function Stretch(Q, L, c) { var S = Q
if (c.length>0) while (S.length<L) { S = c+S }
return S
}
function StrU(X, M, N) { // X>=0.0
var T, S=new String(Math.round(X*Number("1e"+N)))
if (S.search && S.search(/\D/)!=-1) { return ''+X }
with (new String(Stretch(S, M+N, '0')))
return substring(0, T=(length-N)) + '.' + substring(T)
}
function Sign(X) { return X<0 ? '-' : ''; }
function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }

Number.prototype.toFixed= new Function('n','return StrS(this,1,n)')

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

http://msdn.microsoft.com/library/en-us/script56/html/js56jsmthToFixed.asp

===
Postings such as this are automatically sent once a day. Their
goal is to answer repeated questions, and to offer the content to
the community for continuous evaluation/improvement. The complete
comp.lang.javascript FAQ is at http://www.jibbering.com/faq/.
The FAQ workers are a group of volunteers.

FAQ server, Dec 13, 2006

2. ### Dr J R StocktonGuest

In comp.lang.javascript message
<457f428a\$0\$49209\$>, Wed, 13 Dec 2006 00:00:01,
FAQ server <> wrote:

> function Stretch(Q, L, c) { var S = Q
> if (c.length>0) while (S.length<L) { S = c+S }
> return S
> }
> function StrU(X, M, N) { // X>=0.0
> var T, S=new String(Math.round(X*Number("1e"+N)))
> if (S.search && S.search(/\D/)!=-1) { return ''+X }
> with (new String(Stretch(S, M+N, '0')))
> return substring(0, T=(length-N)) + '.' + substring(T)
> }
> function Sign(X) { return X<0 ? '-' : ''; }
> function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }

The functions on my site have been updated since that was put in the
FAQ.

function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }

function PrfxTo(S, L, C) { S += ""
if (C.length>0) while (S.length<L) S = C + S ; return S }

function SpcsTo(S, L) { S += "" // SpcsTo is a reduction of PrfxTo
while (S.length<L) S = " " + S ; return S }

function StrU(X, M, N) { // X > -0.5e-N ; to M digits point N digits
var S = String(Math.round(X*Math.pow(10, N)))
if (/\D/.test(S)) return SpcsTo(X, M+N+1) // cannot cope
S = PrfxTo(S, M+N, '0') ; var T = S.length - N
return S.substring(0, T) + '.' + S.substring(T) }

function StrS(X, M, N) { return Sign(X) + StrU(Math.abs(X), M, N) }

Given that some of the function set are intended to give fixed-width
results, ISTM that Sign should give fixed-width output. When that's
*not* wanted, removing a bit of the code will be easy.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 6
<URL:http://www.jibbering.com/faq/> A FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.

Dr J R Stockton, Dec 13, 2006

3. ### Randy WebbGuest

Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places?

Dr J R Stockton said the following on 12/13/2006 5:32 PM:
> In comp.lang.javascript message
> <457f428a\$0\$49209\$>, Wed, 13 Dec 2006 00:00:01,
> FAQ server <> wrote:
>
>> function Stretch(Q, L, c) { var S = Q
>> if (c.length>0) while (S.length<L) { S = c+S }
>> return S
>> }
>> function StrU(X, M, N) { // X>=0.0
>> var T, S=new String(Math.round(X*Number("1e"+N)))
>> if (S.search && S.search(/\D/)!=-1) { return ''+X }
>> with (new String(Stretch(S, M+N, '0')))
>> return substring(0, T=(length-N)) + '.' + substring(T)
>> }
>> function Sign(X) { return X<0 ? '-' : ''; }
>> function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }

>
> The functions on my site have been updated since that was put in the FAQ.
>
>
>
> function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }
>
> function PrfxTo(S, L, C) { S += ""
> if (C.length>0) while (S.length<L) S = C + S ; return S }
>
> function SpcsTo(S, L) { S += "" // SpcsTo is a reduction of PrfxTo
> while (S.length<L) S = " " + S ; return S }
>
> function StrU(X, M, N) { // X > -0.5e-N ; to M digits point N digits
> var S = String(Math.round(X*Math.pow(10, N)))
> if (/\D/.test(S)) return SpcsTo(X, M+N+1) // cannot cope
> S = PrfxTo(S, M+N, '0') ; var T = S.length - N
> return S.substring(0, T) + '.' + S.substring(T) }
>
> function StrS(X, M, N) { return Sign(X) + StrU(Math.abs(X), M, N) }
>
>
> Given that some of the function set are intended to give fixed-width
> results, ISTM that Sign should give fixed-width output. When that's
> *not* wanted, removing a bit of the code will be easy.

All of the code snippets, every one of them, will be reviewed and
re-written for 10.0 with some documentation and better variable names to
make them easier for newbes to be able to read and learn from. The FAQ
isn't geared to experienced users that can decipher code such as that
above, it is for people who *can't* write code such as that above but
want to learn from it.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

Randy Webb, Dec 14, 2006
4. ### RobGGuest

Randy Webb wrote:
[...]
> All of the code snippets, every one of them, will be reviewed and
> re-written for 10.0 with some documentation and better variable names to
> make them easier for newbes to be able to read and learn from. The FAQ

[...]
> is for people who *can't* write code such as that above but
> want to learn from it.

Amen to that.

--
Rob

RobG, Dec 14, 2006
5. ### Dr J R StocktonGuest

In comp.lang.javascript message <>,
Wed, 13 Dec 2006 21:35:57, Randy Webb <> wrote:
>
>All of the code snippets, every one of them, will be reviewed and re-
>written for 10.0 with some documentation and better variable names to
>make them easier for newbes to be able to read and learn from. The FAQ
>isn't geared to experienced users that can decipher code such as that
>above, it is for people who *can't* write code such as that above but
>want to learn from it.

Where a FAQ entry is headed by a request for an algorithm, a coding
tutorial is not called for. The Notes are the place for that.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)

Dr J R Stockton, Dec 14, 2006
6. ### Randy WebbGuest

Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places?

Dr J R Stockton said the following on 12/14/2006 4:09 PM:
> In comp.lang.javascript message <>,
> Wed, 13 Dec 2006 21:35:57, Randy Webb <> wrote:
>> All of the code snippets, every one of them, will be reviewed and re-
>> written for 10.0 with some documentation and better variable names to
>> make them easier for newbes to be able to read and learn from. The FAQ
>> isn't geared to experienced users that can decipher code such as that
>> above, it is for people who *can't* write code such as that above but
>> want to learn from it.

>
> Where a FAQ entry is headed by a request for an algorithm, a coding
> tutorial is not called for. The Notes are the place for that.

Is there a point to that? I will repeat what I said "All of the code
snippets, every one of them, will be reviewed and *rewritten for 10.0*.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

Randy Webb, Dec 15, 2006
7. ### krsGuest

On Dec 13 2006, 2:32 pm, Dr J R Stockton <>
wrote:
> FAQ server <> wrote:
> The functions on my site have been updated since that was put in the
> FAQ.
>
> function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }
>
> function PrfxTo(S, L, C) { S += ""
> if (C.length>0) while (S.length<L) S = C + S ; return S }
>
> function SpcsTo(S, L) { S += "" // SpcsTo is a reduction of PrfxTo
> while (S.length<L) S = " " + S ; return S }
>
> function StrU(X, M, N) { // X > -0.5e-N ; to M digits point N digits
> var S = String(Math.round(X*Math.pow(10, N)))
> if (/\D/.test(S)) return SpcsTo(X, M+N+1) // cannot cope
> S = PrfxTo(S, M+N, '0') ; var T = S.length - N
> return S.substring(0, T) + '.' + S.substring(T) }
>
> function StrS(X, M, N) { return Sign(X) + StrU(Math.abs(X), M, N) }
>
> Given that some of the function set are intended to give fixed-width
> results, ISTM that Sign should give fixed-width output. When that's
> *not* wanted, removing a bit of the code will be easy.

can someone else confirm that StrS(1.035,1,2) returns +1.03, instead of
the correct value of +1.04, on Firefox2 (winxp)?
-ks

krs, Jan 16, 2007
8. ### Evertjan.Guest

krs wrote on 16 jan 2007 in comp.lang.javascript:
> On Dec 13 2006, 2:32 pm, Dr J R Stockton
> <> wrote:
>> FAQ server <> wrote:
>> The functions on my site have been updated since that was put in the
>> FAQ.
>>
>> function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }
>>
>> function PrfxTo(S, L, C) { S += ""
>> if (C.length>0) while (S.length<L) S = C + S ; return S }
>>
>> function SpcsTo(S, L) { S += "" // SpcsTo is a reduction of PrfxTo
>> while (S.length<L) S = " " + S ; return S }
>>
>> function StrU(X, M, N) { // X > -0.5e-N ; to M digits point N digits
>> var S = String(Math.round(X*Math.pow(10, N)))
>> if (/\D/.test(S)) return SpcsTo(X, M+N+1) // cannot cope
>> S = PrfxTo(S, M+N, '0') ; var T = S.length - N
>> return S.substring(0, T) + '.' + S.substring(T) }
>>
>> function StrS(X, M, N) { return Sign(X) + StrU(Math.abs(X), M, N) }
>>
>> Given that some of the function set are intended to give fixed-width
>> results, ISTM that Sign should give fixed-width output. When that's
>> *not* wanted, removing a bit of the code will be easy.

>
> can someone else confirm that StrS(1.035,1,2) returns +1.03, instead
> of the correct value of +1.04, on Firefox2 (winxp)?

Both FF2.0.0.1 and IE7 return:

+1.03

Why would +1.04 be the correct value?

--
Evertjan.
The Netherlands.

Evertjan., Jan 16, 2007
9. ### VKGuest

Evertjan. wrote:
> > can someone else confirm that StrS(1.035,1,2) returns +1.03, instead
> > of the correct value of +1.04, on Firefox2 (winxp)?

>
> Both FF2.0.0.1 and IE7 return:
>
> +1.03
>
> Why would +1.04 be the correct value?

Because:
If the number you are rounding is followed by 5, 6, 7, 8, or 9, the
number has to be rounded up.
If the number you are rounding is followed by 0, 1, 2, 3, or 4, round
the number down.

If some other rounding logic implemented then it must be spelled in the

In this aspect the native toFixed method follows the common rounding
rules only on IE (JScript):

Both FF and Opera show 1.03

But alert(1.036.toFixed(2)); // show 1.04 on all test browsers

This way FF and Opera seems implementing an altered rounding rule:

If the number you are rounding is followed by 6, 7, 8, or 9, the number
has to be rounded up.
If the number you are rounding is followed by 0, 1, 2, 3, 4 or 5 round
the number down.

Could anyone comment on "the bugs in JScripts implementation" - what is
exactly meant by that?

VK, Jan 16, 2007
10. ### Evertjan.Guest

FAQ server wrote on 13 dec 2006 in comp.lang.javascript:

> -----------------------------------------------------------------------
> FAQ Topic - How do I convert a Number into a String with exactly 2
> decimal places?
> -----------------------------------------------------------------------
>
> When formatting money for example, to format 6.57634 to
> 6.58, 6.5 to 6.50, and 6 to 6.00?
>
> Rounding of x.xx5 is uncertain, as such numbers are not
> represented exactly.
>
> N = Math.round(N*100)/100 only converts N to a Number of value
> close to a multiple of 0.01; but document.write(N) does not give
> trailing zeroes.
>
> ECMAScript Ed. 3.0 (JScript 5.5 [but buggy] and JavaScript 1.5)
> introduced N.toFixed, the main problem with this is the bugs in
> JScripts implementation.
>
> Most implementations fail with certain numbers, for example 0.07.
> The following works successfully for M>0, N>0:
>
> function Stretch(Q, L, c) { var S = Q
> if (c.length>0) while (S.length<L) { S = c+S }
> return S
> }
> function StrU(X, M, N) { // X>=0.0
> var T, S=new String(Math.round(X*Number("1e"+N)))
> if (S.search && S.search(/\D/)!=-1) { return ''+X }
> with (new String(Stretch(S, M+N, '0')))
> return substring(0, T=(length-N)) + '.' + substring(T)
> }
> function Sign(X) { return X<0 ? '-' : ''; }
> function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }
>
> Number.prototype.toFixed= new Function('n','return StrS(this,1,n)')

1
I would prefer to use regex when molding a string into shape:

<script type='text/javascript'>

function toFixed2prot(N) {
var re = new RegExp('(\d{'+N+'})\$','')
return Math.floor(this*Math.pow(10, N)+.5).toString()
.replace(/(\d{2}\$)/,'.\$1')
}

Number.prototype.toFixed2 = toFixed2prot

// testing:

var x = (1.0351).toFixed2(2)
document.write(x+'<br>')
var x = (1.035).toFixed2(2)
document.write(x+'<br>')

</script>

--
Evertjan.
The Netherlands.

Evertjan., Jan 16, 2007
11. ### Evertjan.Guest

VK wrote on 16 jan 2007 in comp.lang.javascript:

> Evertjan. wrote:
>> > can someone else confirm that StrS(1.035,1,2) returns +1.03, instead
>> > of the correct value of +1.04, on Firefox2 (winxp)?

>>
>> Both FF2.0.0.1 and IE7 return:
>>
>> +1.03
>>
>> Why would +1.04 be the correct value?

>
> Because:
> If the number you are rounding is followed by 5, 6, 7, 8, or 9, the
> number has to be rounded up.
> If the number you are rounding is followed by 0, 1, 2, 3, or 4, round
> the number down.
>

True, if you define it that way, but a totally wrong argument.

document.write(1.035 + 0.005);

will return:

1.0399999999999998

so a decimal string like 1.035 seems to be internally represented and
stored by something a bit less than exactly 1.035.

When rounding 1.035 so in reality something like 1.0344444444444449,
would you expect the .toFixed to make an educated guess if
eiter 1.035 or 1.0344444444444449 was entered, as a string of the source
code or in a user input, before it was stored?

No. I for one would not! That is not the job expected from either
Math.round() or .toFixed().

I would have those functions to do exactly what is intended and fix the
problem of the binary conversion [the root of all this evil] sepretately.

If I needed to have an exact BCD [Binary Coded Decimal] effect,
I better construct this myself using strings or integer values with
exponents.

====================

btw:

That

document.write(1.035);

outputs:

1.035

is probably an effect of internal rounding by the write()

document.write(1.0344444444444449);

outputs:

1.034444444444445

also a rounding effect, it seems.

--
Evertjan.
The Netherlands.

Evertjan., Jan 16, 2007
12. ### VKGuest

Evertjan. wrote:
> document.write(1.035 + 0.005);
>
> will return:
>
> 1.0399999999999998
>
> so a decimal string like 1.035 seems to be internally represented and
> stored by something a bit less than exactly 1.035.

I thought that the proposed proc was for rounding _provided_ numbers,
not for rounding internal IEEE-754 representations. The whole purpose
of such algorithm IMO is to make as close as possible i) the strict
"human" math learned at the school and ii) the approximate PC math. If
it was not a purpose then this code is misplaced to FAQ - let it be
moved to some PC-math specific site. For a user seeking for a quick
US\$ calculated price of 10.05 is really internally stored as
10.05XXXXXXXXXXX. All she wants to know is now to round it without
monetarily abusing himself or her buyer.

> When rounding 1.035 so in reality something like 1.0344444444444449,
> would you expect the .toFixed to make an educated guess if
> eiter 1.035 or 1.0344444444444449 was entered, as a string of the source
> code or in a user input, before it was stored?

Yes, absolutely. Rounding goes from rightmost number to left, with
0,1,3,4 rounded down and 5,6,7,8,9 rounded up. This is the school/bank
math and the proc either has to work this way or no use of it.

>1.0344444444444449
>1.034444444444445
>1.03444444444445
>1.0344444444445
>1.034444444445
>1.03444444445
>1.0344444445
>1.034444445
>1.03444445
>1.0344445
>1.034445
>1.03445
>1.0345
>1.035

If some proc cannot outperform this then no use to start the mess on
the first place, as there are no advantages over the native toFixed()
method.

VK, Jan 16, 2007
13. ### Evertjan.Guest

VK wrote on 16 jan 2007 in comp.lang.javascript:

> If some proc cannot outperform this then no use to start the mess on
> the first place, as there are no advantages over the native toFixed()
> method.
>

Indeed.

However, I think there where / are some real bugs in .toFixed,
that have to be fixed. John S. knows such things.

However having or building a BCD library or using integer cents/pennies
throughout is always a possibility, when dealing with currency.

--
Evertjan.
The Netherlands.

Evertjan., Jan 16, 2007
14. ### Richard CornfordGuest

VK wrote:
> Evertjan. wrote:
>> document.write(1.035 + 0.005);
>>
>> will return:
>>
>> 1.0399999999999998
>>
>> so a decimal string like 1.035 seems to be internally represented
>> and stored by something a bit less than exactly 1.035.

>
> I thought

If you appreciated for yourself how badly you do that you might be in a
position to see it as flagging the imminent arrival of another of your
streams of irrational, irrelevant, ill-considered and worthless
nonsense. Of course to appreciate your shortcomings you would have to
not suffer from them.

> that the proposed proc was for rounding _provided_ numbers,
> not for rounding internal IEEE-754 representations.

In a system where all numbers are IEEE floating point numbers it is not
possible to provide a number in any other form.

> The whole purpose of such algorithm IMO

You opinions are, as always, wothless.

> is to make as close as possible i) the strict "human" math
> learned at the school

Where in school? Basic arithmetic classes, introductory statistics, at
Accountancy school, degree level pure mathematics?

> and ii) the approximate PC math.

"And"? And what is "approximate PC math"? You have spouted a great deal
of twaddle on the subject of number representations in computers over
the years, which has made it obvious that you hardly understand what
computers do (or can do) when representing and manipulating numbures.

> If it was not a purpose then this code is misplaced to
> FAQ -

The code in the FAQ is intended to be an alternative to - toFixed - that
produces the same output as the ECMA 262 specified algorithm for -
toFixed - (ECMA 262. 3rd Ed. section 15.7.4.5). This allows for
consistent and predictable behaviour in the face of implementation bugs
in - toFiexed -, and says nothing as to the appropriateness of the code
(or of - toFixed -) for any particular task.

> let it be moved to some PC-math specific site.

An alternative to - tofixed - is appropriate in a javascript FAQ.

> For a user seeking for a quick answer it is irrelevant that
> US\$ calculated price of 10.05 is really internally stored as
> 10.05XXXXXXXXXXX. All she wants to know is now to round it
> without monetarily abusing himself or her buyer.

You won't see it (being fundamentally incompetent yourself) but for
someone attempting to program a system that handles currency to take
such a cavalier attitude would be inept.

Because I have worked with them I know that UK share trading systems
employ 64 bit integer values for all currency values (representing
multiples of 1/1000 of the currency unit) and only perform integer
arithmetic on those values. Thus fractional results are truncated, not
rounded.

>> When rounding 1.035 so in reality something like 1.0344444444444449,
>> would you expect the .toFixed to make an educated guess if
>> eiter 1.035 or 1.0344444444444449 was entered, as a string of the
>> source code or in a user input, before it was stored?

>
> Yes, absolutely.

Why am I not surprised by that?

> Rounding goes from rightmost number to left, with
> 0,1,3,4 rounded down and 5,6,7,8,9 rounded up.

So you think that there is only one way to round a number?

> This is the school/bank math

You have never heard of "Banker's rounding"? And never been educated
beyond basic arithmetic?

> and the proc either has to work this way or no use of it.

That is so often you answer. You encounter something that does not work
the way your deranged mind expects and so you declare it unusable.

>>1.0344444444444449
>>1.034444444444445
>>1.03444444444445
>>1.0344444444445
>>1.034444444445
>>1.03444444445
>>1.0344444445
>>1.034444445
>>1.03444445
>>1.0344445
>>1.034445
>>1.03445
>>1.0345
>>1.035

>
> If some proc cannot outperform this then no use to start
> the mess on the first place, as there are no advantages
> over the native toFixed() method.

While the native - toFixed - method produces inconsistent results across
implementations (and particularly while it is evidently faulty in IE) a
consistent alternative has many advantages. It may be that what you
think the code should do is not what it does do, and it may be that it
is inappropriate for many of the tasks that the inconsiderate would
apply it to (particularly systems handling currency), but so long as
what it does do is consistent then its use is appropriate in contexts
where that is the desired behaviour.

Richard.

Richard Cornford, Jan 16, 2007
15. ### VKGuest

Richard Cornford wrote:
<snip irrelevant>
> The code in the FAQ is intended to be an alternative to - toFixed - that
> produces the same output as the ECMA 262 specified algorithm for -
> toFixed - (ECMA 262. 3rd Ed. section 15.7.4.5).

On the entire Earth there are 2 to many 3 people giving some sh** on
such subject. This way for FAQ it is irrelevant

> This allows for
> consistent and predictable behaviour in the face of implementation bugs
> in - toFiexed -, and says nothing as to the appropriateness of the code
> (or of - toFixed -) for any particular task.

FAQ Topic - How do I convert a Number into a String with exactly 2
decimal places?
-----------------------------------------------------------------------
When formatting money for example, to format 6.57634 to
6.58, 6.5 to 6.50, and 6 to 6.00?
<snip>

So I would propose to remove all this irrelevant self-exposure stuff -
I am taking that JRS is cool in all imaginable aspects of math, but
this poor FAQ topic is not a place to fall it out.

Just answer straight to the question with the promised results, so
6.57634 becomes 6.58
and - by the way -
1.035 becomes 1.04

P.S. Obviously when someone is asking "How do I convert 10.5678 into a
String with exactly 2 decimal places?"
she doesn't mean " "How do I convert 10.5678 into 10.56". Even for ones
with C on calculus the presumed result is 10.57 and not 10.56
Thus way "how to round?" is always presumed, not "how to truncate". For
the latter a one-liner code is sufficient. What do IEEE-754 or
IEEE-754r tell is irrelevant for this FAQ: though anyone is welcome to
analyze it up to any depth in personal blog and advertise in post
signatures.

VK, Jan 16, 2007
16. ### Dr J R StocktonGuest

In comp.lang.javascript message <
glegroups.com>, Mon, 15 Jan 2007 18:08:14, krs <>
posted:
>
>can someone else confirm that StrS(1.035,1,2) returns +1.03, instead of
>the correct value of +1.04, on Firefox2 (winxp)?

It should on all systems return +1.03, because
1.035*100 -> 103.49999999999998
in IEEE Doubles.

If you want exact results for currency including halfpennies, you need
to work in units such that halfpenny quantities are stored exactly.
Study the second paragraph of the FAQ entry.

Read IEEE 754, if that's the right number; ECMA 262 should tell you.

The code in the FAQ is not exactly what I currently use.

<FAQENTRY>
The FAQ lacks the word "currency" which might well be a search target.

IMHO it would be better to omit the first three words of FAQ 4.6, "When
formatting money" and to create a new 4.x on the general topic of "How
should currency calculations be done?".

Points to include : reference to 4.6 & 4.7; distinction between
accounting (must be exact) and finance (often approximate)<g>[*]</g>;
converting to new currencies (e.g. DMk to Euro) has exact rules.

</FAQENTRY>

For the handling of currency (in Delphi), Google News for "Herbster" and
for "JohnH".

Any astrodynamicists or orbital mechanics here?

[*] "A billion here, a billion there ... it soon adds up to real
money!".

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links;
Astro stuff via astron-1.htm, gravity0.htm ; quotings.htm, pascal.htm, etc.
No Encoding. Quotes before replies. Snip well. Write clearly. Don't Mail News.

Dr J R Stockton, Jan 16, 2007
17. ### Dr J R StocktonGuest

In comp.lang.javascript message <eoiva2\$cqn\$1\$>
, Tue, 16 Jan 2007 16:42:41, Richard Cornford
<> posted:

>In a system where all numbers are IEEE floating point numbers it is not
>possible to provide a number in any other form.

One might consider that to be tautological.

But one can represent numbers in other ways. In strings, for example,
or in arrays/objects. I have Pascal code for computing with integers of
up to about 65000 digits (bases 2 to 16), though the largest native size
is 32-bit.

>The code in the FAQ is intended to be an alternative to - toFixed - that
>produces the same output as the ECMA 262 specified algorithm for -
>toFixed - (ECMA 262. 3rd Ed. section 15.7.4.5). This allows for
>consistent and predictable behaviour in the face of implementation bugs
>in - toFiexed -, and says nothing as to the appropriateness of the code
>(or of - toFixed -) for any particular task.

Not in the opinion of its author. The code was intended to do the
required job, including leading zeroes or spaces, as is commonly
required and generally provided in other languages. It was NOT intended
to match a (debugged) toFixed.

>Because I have worked with them I know that UK share trading systems
>employ 64 bit integer values for all currency values (representing
>multiples of 1/1000 of the currency unit) and only perform integer
>arithmetic on those values. Thus fractional results are truncated, not
>rounded.

Truncation is not a necessary consequence.
Delphi "currency" type is scaled by 10,000.

>>> When rounding 1.035 so in reality something like 1.0344444444444449,
>>> would you expect the .toFixed to make an educated guess if
>>> eiter 1.035 or 1.0344444444444449 was entered, as a string of the
>>> source code or in a user input, before it was stored?

In such cases, the algorithm should round to, say, an integer of
micropounds, convert to string, add a decimal point and chop trailing
zeroes as needed.

>Why am I not surprised by that?
>
>> Rounding goes from rightmost number to left, with
>> 0,1,3,4 rounded down and 5,6,7,8,9 rounded up.

Unreasonable anti-2 prejudice.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 6
news:comp.lang.javascript FAQ <URL:http://www.jibbering.com/faq/index.html>.
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.

Dr J R Stockton, Jan 16, 2007
18. ### Richard CornfordGuest

Dr J R Stockton wrote:
> Richard Cornford posted:
>
>> In a system where all numbers are IEEE floating point numbers
>> it is not possible to provide a number in any other form.

>
> One might consider that to be tautological.

It is tautological. VK is the only person who would ever need being told
(and probably would not see the inevitability even then).

> But one can represent numbers in other ways.

Where a number is an entity of a strictly defined type and form being a
representation of a number is not necessarily being a number. Otherwise,
yes. Numbers, in the mathematical sense, can be represented in all sorts
of ways in javascript, and arbitrary mathematical operations applied to
those representations by javascript code.

<snip>
>> The code in the FAQ is intended to be an alternative to - toFixed -
>> that produces the same output as the ECMA 262 specified algorithm
>> for - toFixed - (ECMA 262. 3rd Ed. section 15.7.4.5). This allows
>> for consistent and predictable behaviour in the face of
>> implementation bugs in - toFiexed -, and says nothing as to the
>> appropriateness of the code (or of - toFixed -) for any particular

>
> Not in the opinion of its author. The code was intended to do the
> required job, including leading zeroes or spaces, as is commonly
> required and generally provided in other languages. It was NOT
> intended to match a (debugged) toFixed.

Fair enough. I wrote a step-by-step implementation of the - toFixed -
algorithm to verify bugs in implementations, and it is not a piece of
code that I would want to use.

>> Because I have worked with them I know that UK share trading
>> systems employ 64 bit integer values for all currency values
>> (representing multiples of 1/1000 of the currency unit) and
>> only perform integer arithmetic on those values. Thus
>> fractional results are truncated, not rounded.

>
> Truncation is not a necessary consequence.
> Delphi "currency" type is scaled by 10,000.
>
>>>> When rounding 1.035 so in reality something like
>>>> 1.0344444444444449, would you expect the .toFixed to make an
>>>> educated guess if
>>>> eiter 1.035 or 1.0344444444444449 was entered, as a string of the
>>>> source code or in a user input, before it was stored?

>
> In such cases, the algorithm should round to, say, an integer of
> micropounds, convert to string, add a decimal point and chop
> trailing zeroes as needed.

<snip>

You cannot pay out, or receive, a micropound. Centipouds are as small as
British money gets

Richard.

Richard Cornford, Jan 17, 2007
19. ### Dr J R StocktonGuest

In comp.lang.javascript message <Xns98BA88CBE8778eejj99@194.109.133.242>
, Tue, 16 Jan 2007 12:26:51, Evertjan. <>
posted:
>I would prefer to use regex when molding a string into shape:

Agreed.

Here's a rough first try, undertested, unsigned, PrfxTo cf FAQ 4.6
Stretch :-

function Hasty1(X) { var Y, Z, Q=0 // Trunc; Q=5 to Round. Bankers???
Y = String(Math.round(X*1000)+Q)
Z = PrfxTo(Y, 4, "0").replace(/(\d\d)(\d)\$/, ".\$1")
return Z }

OTOH, for a variable number of decimal places, substr/substring may be
easier than RegExp.

--
(c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 6
news:comp.lang.javascript FAQ <URL:http://www.jibbering.com/faq/index.html>.
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.

Dr J R Stockton, Jan 17, 2007
20. ### Evertjan.Guest

Dr J R Stockton wrote on 17 jan 2007 in comp.lang.javascript:

> In comp.lang.javascript message <Xns98BA88CBE8778eejj99@

194.109.133.242>
> , Tue, 16 Jan 2007 12:26:51, Evertjan. <>
> posted:
>>I would prefer to use regex when molding a string into shape:

>
> Agreed.
>
> Here's a rough first try, undertested, unsigned, PrfxTo cf FAQ 4.6
> Stretch :-
>
> function Hasty1(X) { var Y, Z, Q=0 // Trunc; Q=5 to Round.
> Y = String(Math.round(X*1000)+Q)

Y = String(Math.floor(X*1000+Q))

> Z = PrfxTo(Y, 4, "0").replace(/(\d\d)(\d)\$/, ".\$1")

You would not need the second ()

Z = ... .replace(/(\d\d)\d\$/, ".\$1")

> return Z }

Would it be an idea if one defines x.xx5 as always round up,
thinking for the moment only of positive values,

round: Q = 5.0001

floor: Q = 0.0001

Is it true that the binary converion problem always gives result
differences that are slightly to low, [or correct of course]?

> Bankers???

Personally, I do not need or want this silly idea of toggled rounding.
It is not important in scientific measurement, where an exact value is
never obtained anyway, only with currency, perhaps, in the amount
nonvirtual mortals only dream of.

So it cannot be that important in clientside(!) javascript.

> OTOH, for a variable number of decimal places, substr/substring may be
> easier than RegExp.

var Q = .0001 //5.0001
var NN = 1; for var i=0;i<N;i++) NN*=10
var Y = String(Math.floor(X*NN+Q))
..... .replace(new RegExp("(\\d{"+N+"})\\d\$"), ".\$1")
[N>0]

or:

var NN='1000000000000'.substr(0,N+1)

--
Evertjan.
The Netherlands.