How are JS numbers represented internally??

T

Thomas 'PointedEars' Lahn

VK said:
Troll? I'm answering the OP's question.

You have been misinforming the OP. Again. Because you have no clue what
you are talking about.
From the developer point of view IMHO it is important to know exactly
the border after wich say ((x-1) == x) is true or say alert(x) displays
a value which is 50,000 (fifty thousands) lesser then the actual value.

And this value can be easily computed using the algorithm described.
It cannot be obtained by making wild guesses, as you did.
That may doesn't have any sense - but it sounds rather reasonnable for
my twisted mind. :)

No surprise here.


PointedEars
 
V

VK

Thomas said:
And this value can be easily computed using the algorithm described.

Right, this is called BigMath and a number obtained this way is called
BigInt. BigMath is very resource expensive but it used in many domains
where the regular machine precision limits are too narrow.

It has nothing to do with the OP's question, rather then the question
could be rephrased: "From what point I cannot use default language math
for integer and I have to use 3rd party BigMath libraries?"

I never had to use BigMath in JavaScript for my projects, but a friend
of mine siggested (with not obligations) this library:
<http://www.leemon.com/crypto/BigInt.html>
 
T

Thomas 'PointedEars' Lahn

VK said:
^^^^^^^^^^
Right, this is called BigMath

Are you reading what you are replying to? BigMath/BigInt libraries are
about calculating great integer values. IEEE-754 as used in the named
ECMAScript implementations (JavaScript and JScript) is about floating-point
values. Inevitable potential precision loss with floating-point numbers
is the issue here, and the OP wanted to know which is the greatest integer
number that can be stored as IEEE-754 double without precision loss.
That is not anything near 2^32-1, of course.

As I said already, you have no clue what you are talking about.


PointedEars
 
V

VK

Thomas said:
As I said already, you have no clue what you are talking about.

1]
var x = 1;
alert(x == (x-1));

How big must be the number to get "true" in alert?

2]
var x = 1;
alert(x);

How big must be the number to get in alert something only slightly
reflecting the real x value?

I gave the answer, it can be possibly narrowed in some parts for some
implementations.

Your IEEE mentions do not have any practical use so far. Even if you
link IEEE specs thousands times in this thread, it still doesn't answer
the question. And if the questions 1 and 2 for positive integers indeed
can be so easily and evidently conducted from IEEE specs, then where
are *your* answers?
 
T

Thomas 'PointedEars' Lahn

VK said:
Thomas said:
As I said already, you have no clue what you are talking about.

1]
var x = 1;
alert(x == (x-1));

How big must be the number to get "true" in alert?

2]
var x = 1;
alert(x);

How big must be the number to get in alert something only slightly
reflecting the real x value?

I gave the answer,

Not at all.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Dr said:
[...] Thomas 'PointedEars' Lahn [...] posted :
Utter nonsense.

1. It is only a secondary matter of the operating system. It is rather
a matter of Integer arithmetic (with Integer meaning the generic ^^^^^^^^^^^^^^^^^^^^^^^^^^^
machine data type), which can only performed if there is a processor ^^^^^^^^^^^^^^^^^
register that can hold the input and output value of that operation.
On a 32-bit platform, with a 32 bits wide data bus, the largest
register is also 32 bits wide, therefore the largest (unsigned)
integer value that can be stored in such a register is 2^32-1
(0..4294967295, 0x0..0xFFFFFFF hexadecimal)

Incorrect.

No, it is correct.
For example, Turbo Pascal runs on 16-bit machines, and does
not need (though can use) 32-bit registers and/or a FPU.

I have programmed in several Pascal dialects before for years. As you well
know (<URL:http://www.merlyn.demon.co.uk/pas-real.htm#FloatTypes>), Comp is
a special floating-point data type in Turbo Pascal 5.0 and later, to hold
larger integer values (integer != Integer). Like Single, Double, and
Extended, it can only be used if FPU (80x87) software emulation is enabled
(through a compiler switch), or an FPU is present. I mentioned the
possibility of FPU emulation in point 2.

I described general restrictions for Integer (not: integer) arithmetic
here, though.
But, since 1988 or earlier, it has provided the 32-bit LongInt type.
LongInt addition, for example, is provided by two 16-bit ops and a carry.

Note that integer multiplication frequently involves the use of a
register pair for the result.
Irrelevant.


Insufficiently correct.
Nonsense.

The 64-bit "comp" type is implemented *exactly* in the FPU (and is 2's
complement IIRC). It has integer values.

"Integer" refers to the generic Integer machine type, not to the integer
set defined in math, as I already have said.
Also, longer arithmetic can be implemented outside the FPU;
floating-point is not necessary.

I was talking about machine types.
Your use of the word "decimal" is superfluous and potentially
misleading.

Your entire posting is superfluous and potentially misleading.
Nonsense.

2^99 is an integer, and it is represented exactly.

I have not said anything that contradicts this.
I know what you have in mind; but your words do not express it.

Or maybe, just /maybe/, you (deliberately) misunderstood completely.


PointedEars
 
B

bobalong

Thanks everyone for your help.

Can I just reign this back in to my original question, which was more
to do with the max/min limits that are represented in standard decimal
form by javascript:

Q: What is the highest integer (x) that can be represented by the
expression x.toString() such that the returned string does not contain
the letter 'e' (i.e. is in pure decimal form, not exponential notation)?
 
V

VK

Thanks everyone for your help.

Can I just reign this back in to my original question, which was more
to do with the max/min limits that are represented in standard decimal
form by javascript:

Q: What is the highest integer (x) that can be represented by the
expression x.toString() such that the returned string does not contain
the letter 'e' (i.e. is in pure decimal form, not exponential notation)?

I believe it was already answered in this thread (skipping on
irrelevant IEEE side branches).

The biggest number still returned by toString() method "without e"
(thus not converted into exponential form) is 999999999999999930000

But this number is located above the limits of acceptable math I
described in another post. This way say 999999999999999930000 and
999999999999999900000 will be both returned by toString() method as
"999999999999999900000" (30000 rounding error).

This way your question is incorrect as asked. The right question is:
Q: What is the highest integer (x) that can be represented by the
expression x.toString() such that the returned string does not contain
the letter 'e' (i.e. is in pure decimal form, not exponential notation)
AND
does follow the regular human math (so say x > x-1 is true) ?

A:
999999999999999 (15 digits "9") and lesser if you do not plan to use
bitwise operations.
4294967295 and lesser if you plan to use bitwise operations.
 
T

Thomas 'PointedEars' Lahn

VK said:
I believe it was already answered in this thread (skipping on
irrelevant IEEE side branches).

NO, it was not!
The biggest number still returned by toString() method "without e"
(thus not converted into exponential form) is 999999999999999930000

NO, it is not! Try alert(999999999999999930001), fool.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Q: What is the highest integer (x) that can be represented by the
expression x.toString() such that the returned string does not contain
the letter 'e' (i.e. is in pure decimal form, not exponential notation)?

Interpolation showed it is

999999999999999934463

in

- JavaScript 1.3 (Netscape/4.8; build target: i386),
- JavaScript 1.5 (Mozilla/1.7.12; build target: i686-pc-linux-gnu),
- JavaScript 1.6 (Firefox/1.5.0.1; same target),
- Opera/8.52 (build target: i386), and
- KHTML 3.5.1 (Konqueror/3.5; same target).

Tested on GNU/Linux 2.6.15.6 i686.

However, you will observe that truncation of decimal places has had to occur
at this point, since it is way above 2^52-1 (4503599627370495) _and_ the
number of bits to represent the value exactly exceeds the number of
available mantissa bits (52).

See ECMAScript Edition 3 Final, subsection 15.7.4.2
(Number.prototype.toString) referring to subsection 9.8.1.
("ToString applied to the Number type"), for the specified
value.


PointedEars
 
T

Thomas 'PointedEars' Lahn

VK said:
It was originally said "...or round that".

But not here.
999999999999999934469 to be totally exact.

Not here. Which UAs have you tested with, with which OSs, on which
platforms?
[...]
999999999999999 (15 digits) is the upper limit for the OP's question

Wrong. The number of decimal digits does not matter because the value
is not stored in decimal.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Q: What is the highest integer (x) that can be represented by the
expression x.toString() such that the returned string does not contain
the letter 'e' (i.e. is in pure decimal form, not exponential notation)?

Interpolation showed it is

999999999999999934463

in

- JavaScript 1.3 (Netscape/4.8; build target: i386),
- JavaScript 1.5 (Mozilla/5.0 rv:1.7.12; build target: i686-pc-linux-gnu),
- JavaScript 1.6 (Firefox/1.5.0.1; same target),
- Opera/8.52 (build target: i386), and
- KHTML 3.5.1 (Konqueror/3.5; same target).

Tested on GNU/Linux 2.6.15.6 i686.

However, you will observe that truncation of decimal places has had to occur
at this point, since it is way above 2^52-1 (4503599627370495) _and_ the
number of bits to represent the value exactly exceeds the number of
available mantissa bits (52).

See ECMAScript Edition 3 Final, subsection 15.7.4.2
(Number.prototype.toString) referring to subsection 9.8.1.
("ToString applied to the Number type"), for the specified
value.


PointedEars
 
R

Rob

Thank you both very much.

999999999999999934463 is the lucky number here for me. Truncation of
decimal places doesn't matter as I'm dealing with integers only.

Was surprised to hear how slooow BIgMath is (1-10 seconds for a simple
decrement!!) - I'll avoid that at all costs.

Cheers
Rob
 
T

Thomas 'PointedEars' Lahn

Rob wrote:
^^^
This may cause problems, as we already have at least one regular Rob here :)
Thank you both very much.

You are welcome.
999999999999999934463 is the lucky number here for me. Truncation of
decimal places doesn't matter as I'm dealing with integers only.

I meant the truncation of binary "decimal" places of the mantissa-exponent
representation of the stored floating-point value. Just follow the
algorithm:

0. Let n be 999999999999999934463.

1. Convert n to binary:

,----------------------------- 70 bits ------------------------------.
N := 1101100011010111001001101011011100010111011110100111101111111111111111

[bc(1) rulez :)]

2. Let the mantissa M be 1 <= M < 10 (binary):

,--------------------------- 69 bits -------------------------------.
M := 1.101100011010111001001101011011100010111011110100111101111111111111111
^[1]

E := 1000101 (69d)

3.1 Ignore the "1." to allow for greater precision:

,--------------------- 52 bits --------------------.
M := 101100011010111001001101011011100010111011110100111101111111111111111

These are 69 of available 52 bits for the mantissa M. Therefore,

3.2. Truncating the "binary" decimal places[^1]

leads to

S := 0
E := 10001 (17d) + bias
M := (1)1011000110101110010011010110111000101110111101001111

Therefore, the actual binary value stored is

1101100011010111001001101011011100010111011110100111100000000000000000

and the actual decimal value stored is

999999999999999868928(d)
^^
which is displayed rounded by .toString() as

999999999999999900000
^^^^^
Now compare with the intended value:

999999999999999934463
^^^^^

The difference to the intended value is 65535 when stored, 34463 when
displayed. Most certainly that does matter here, even if you are only
dealing with integers. I thought that would be clear to you already
by VK mentioning it correctly several times in this thread.


PointedEars
 
L

Lasse Reichstein Nielsen

[a very nice and precise derivation of the limit]

So, in summary:

The limit on integers that can be used with bitwise operations:
2^32-1 = 4294967295

The limit on integers that can all be represented exactly:
2^53 = 9007199254740992
(i.e., 2^53+1 is the first integer that cannot be represented by
the number type)

The limit on representable numbers that does not display in scientific
notation (largest representable number below 10^21):
10^21-2^17 = 999999999999999868928

Limit on number literals that are converted to this number:
10^21-2^16-1 = 999999999999999934463
(above this, the number is closer to 10^21, which can itself be
represented exactly)

/L
 
T

Thomas 'PointedEars' Lahn

Lasse said:
[a very nice and precise derivation of the limit]

Thank you :)
So, in summary:

The limit on integers that can be used with bitwise operations:
2^32-1 = 4294967295

The limit on integers that can all be represented exactly:
2^53 = 9007199254740992

= 9.007199254740992E15
(i.e., 2^53+1 is the first integer that cannot be represented by
the number type)

True. However, I think the _greatest_ integer that can be represented
exactly, is

(2^54-1)*(2^11-2-1023)
= (2^54-1)*(2^10-1)
= 18428729675200068609
= 1.8428729675200068609E19

because there are 52 bits for the mantissa (the leading 1 of 2^54-1, which
requires 53 bits, stripped), and the bias (+1023) for the exponent makes
the latter different from 2^11-1 = 2047 (Infinity/NaN) then.

Let L be the least integer that cannot be represented exactly, and let G be
the greatest integer that can be represented exactly: It is a peculiarity
of floating-point formats such as IEEE-754 that there are integers N with
L < N < G that can that can be represented exactly anyway; take 2^54-2 and
2^55-4, for example.[1] (However, there are more integers in the named
range that cannot be represented exactly, so this knowledge is merely of
academical value, or when you are knowing which numbers you will be dealing
with.)


PointedEars
___________
[1] ISTM that this set is defined as follows:

N := {x : 2^(||m|| + 1),
: 2^(||m|| + n) - 2^(n - 1); n elementOf(â„•), n > 1}

where ||m|| is the length of the mantissa m.
 
D

Dr John Stockton

JRS: In article <[email protected]>
, dated Tue, 21 Mar 2006 00:49:29 remote, seen in
news:comp.lang.javascript said:
<http://groups.google.com/group/comp.lang.javascript/tree/browse_frm/thread/38d2
1acb4d4509ce/605c4236958ed554?rnum=31&hl=en&_done=%2Fgroup%2Fcomp.lang.javascrip
t%2Fbrowse_frm%2Fthread%2F38d21acb4d4509ce%2Fc61f73ac60f10e2c%3Fhl%3Den%26#doc_3
833df1762d81fee>

Clear, plain and simple! :)

Should it be a <FAQENTRY> or a FAQ Note now? (with necessary mention
that it is correct for 32bit machines and of some JavaScript/JScript
math discrepancies)

The 32-bit limit on logical operations is in ECMA-262 and applies
independently of the bit-size of the machine, whatever it may be.

Likewise the Number type is defined as an IEEE Double independently of
the machine architecture.

Of course, on machines which don't have a 32-bit architecture and/or
don't have an IEEE 754 compatible FPU, there's an increased risk of non-
compliance with ECMA.
 
D

Dr John Stockton

JRS: In article <[email protected]>
, dated Tue, 21 Mar 2006 04:10:23 remote, seen in
news:comp.lang.javascript said:
Also I guess (only guess) that indirectly it answers on another
occasional question: "What is the longest string value allowed in
JavaScript?" Skipping on mechanical limits (memory), by language itself
I would say that it's 9007199254740992 characters or lesser to be able
to use any of string methods (otherwise rounding error for length will
kill them).

Characters are Unicode, so one should probably think of a number and
halve it, allowing 2 bytes per character. ECMA says they are 16 bits.

ISTM much more likely that the internal indexing will be done with a
true integer and not a float.

ECMA says that strings consist of all finite sequences, which means that
the length is unbounded. I think they need to think that out again;
there's not room in the observable universe for all finite numbers; and
not for even the infinitesimal fraction smaller than, say, 10^1000.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top