To clarify the problem we are discussing, when a string is parsed into a
number, and the string is representing a very large number, the
number does
not yield the expected results when used in an operation. This is
demonstrated in the first modulo experiment. This issue does not
exist in
AVM1 or JVM.
On 3/7/07, elibol <[EMAIL PROTECTED]> wrote:
>
> Thank you Jim.
>
> "From previous data packing experiments, I've found that the last
nibble
> (4 bits) of a 64-bit Number isn't reliable when you're casting to and
> from Numbers (e.g . reading 8 bytes out of a ByteArray into a
Number or
> doing round-trips via the toString and parseFloat methods). I'm not
> sure why this is the case--perhaps someone from Adobe can reply and
> speak to this particular issue."
>
> This seems relevant, as 6.3e+51 would require an allocation of 3 64
bit
> Numbers (approx. 173) to be represented, using at least 2 sets of
those 4
> unreliable bits you've mentioned. Is this correct?
>
> Is there a solution/technique for correctly representing such parsed
> Numbers? The subject Number will be concerned with properly
representing its
> value in order to be used in any operation supported by as3.
>
> Is it impossible to write a parseFloat function that would correctly
> parse Numbers under this specification?
>
> Thank you Fumio and Jim.
>
> On 3/6/07, Jim Cheng <[EMAIL PROTECTED]> wrote:
> >
> > Fumio Nonaka wrote:
> > > 2 floating point numbers are NOT "close enough". That IS the
> > problem.
> > >
> > > var _str:String = "1.2e+51";
> > > var n:Number = parseFloat(_str);
> > > trace(( n-1.2e+51 ) > 100000000000000000000000000000000000); //
> > true
> >
> > In ActionScript 3, the native Number data type is internally
> > represented
> > as a IEEE-754 double-precision floating-point number. Due to the
way
> > that the IEEE-754 standard defines how the bits are used to
represent
> > the number, the accuracy of the mantissa precision (always 52
bits, or
> > 16 decimal digits) changes depending on the exponent (always 11
bits).
> >
> > See: http://en.wikipedia.org/wiki/IEEE_754
> >
> > This is to say, the "close enough" value that you need to compare
the
> > absolute difference between the two Numbers scales in magnitude with
> > the
> > exponent. This can be particularly bad if you need arbitrary
> > precision,
> > (e.g. when doing financial or scientific calcuations), as while
> > 1.32e+36
> > is paltry compared to 1.2e+51, no one would want to be swindled
out of
> > 1.32e+36 dollars due to faulty floating point comparisons, hence the
> > need for arbitrary precision integer libraries for such applications
> > as
> > was recently mentioned on this list.
> >
> > Fortunately however, if you don't need this kind of exact precision,
> > but
> > simply need to match large values originally parsed from strings to
> > Numbers as per your example, there is a much better and easier
way to
> > compare very large Numbers in ActionScript 3--by inspecting them at
> > the
> > bit level following the IEEE-754 specification.
> >
> > From previous data packing experiments, I've found that the last
> > nibble
> > (4 bits) of a 64-bit Number isn't reliable when you're casting to
and
> > from Numbers (e.g. reading 8 bytes out of a ByteArray into a
Number or
> > doing round-trips via the toString and parseFloat methods). I'm not
> > sure why this is the case--perhaps someone from Adobe can reply and
> > speak to this particular issue.
> >
> > That being said, all you really need to do for a nearly-equals
Number
> > comparison is a byte-by-byte comparison save for the last byte, in
> > which
> > case you only compare the four most significant bits. If all bits
> > aside
> > from the last nibble match, the Numbers are close enough.
> >
> > Here's how I do it:
> >
> > <code>
> >
> > /**
> > * Compare two ActionScript 3 Numbers for near-equality.
> > *
> > * @param The first Number
> > * @param The second Number
> > *
> > * @return True on near-equality, false otherwise.
> > */
> > public function closeEnough(a:Number, b:Number):Boolean {
> > var ba:ByteArray, i:uint;
> > if (a == b) {
> > // A is explicitly equal to B
> > return true;
> > }
> > else {
> > // A isn't exactly equal to B, so we need to
> > // check the Numbers' bytes one byte at a time.
> > ba = new ByteArray();
> > ba.writeDouble(a);
> > ba.writeDouble(b);
> >
> > // If any of the first 7 bytes differ, then
> > // the two values are not close enough.
> > for (i = 0; i < 7; i++) {
> > if (ba[i] != ba[i + 8]) {
> > return false;
> > }
> > }
> >
> > // Mask the last four bits out and compare the
> > // last byte. If they match, the Numbers are
> > // close enough. The last nibble tends not to
> > // be reliable enough for comparison, so we
> > // allow these to differ and the two Numbers
> > // still be considered close enough.
> > if ((ba[7] & 0xf0) != (ba[15] & 0xf0)) {
> > return false;
> > }
> > }
> > return true;
> > }
> >
> > </code>
> >
> > Jim Cheng
> > effectiveUI
> > _______________________________________________
> > [email protected]
> > To change your subscription options or search the archive:
> > http://chattyfig.figleaf.com/mailman/listinfo/flashcoders
> >
> > Brought to you by Fig Leaf Software
> > Premier Authorized Adobe Consulting and Training
> > http://www.figleaf.com
> > http://training.figleaf.com
> >
>
>