ES Decimal status
Mike Cowlishaw
MFC at uk.ibm.com
Thu Sep 25 07:24:57 PDT 2008
[Was on airplanes since my last post, arrived late in SeaTac ... will try
and consoliate replies on this thread to one e-mail :-)]
> >> I'm not sure what you are getting at. a[1] and a[1.000] refer to the
> >> same property in ECMAScript, but a[1m] and a[1.000m] would not. Are
> >> you saying this isn't a problem?
> >
> > Absolutely not a problem ... many languages (and ES itself) which
> > index
> > 'arrays' by strings treat the index "1.000" as different from "1", and
> > this is not considered a problem.
>
> But they do not treat 1.000 as an index differently from 1. Explicit
> string indexes, whether literally expressed or computed, are not the
> issue here.
[and later:]
> I should have written "explicitly string-typed indexes", or perhaps
> "intentionally string-type indexes".
>
> So far, intentions aside, people writing JS can and arguably do count
> on any integer result of an index computation being equivalent to
> that index expressed literally as the === integer constant with no
> trailing zeroes after the decimal point.
>
> This a === b => o[a] is o[b] invariant (ignore the tiny number
> exceptions; I agree they're undesirable spec bugs) is what folks on
> the list are concerned about breaking, for integral values.
> Fractional index values and strings consisting of numeric literals
> with and without trailing zeroes are different use-cases, not of
> concern.
OK, and also liorean says:
> I'm of the opinion that decimal128 and binary64 should behave
identically in as many areas as possible.
That's a valid model. I suppose I see strings and decimals as being
'closer' in concept, and in both "what you see is what you get". But for
arrays, I see the problem. In that case 'reduce to shortest form, that is
strip trailing zeros, might be the right thing to do for decimals used as
array indices. That function is in Sam's implementation (it's called
'reduce').
> > This is, no doubt, because if one is treating array indexes as a
> > set of
> > integers you use integer operations on those indexes (almost
> > exclusively
> > +, -, and *). If one does use a divide,
>
> Maciej pointed out reciprocal multiplication as strength-reduced
> division; this is done often enough in graphics and other low-level
> code.
Hmm, his example was dividing an integer by 2. Why would one multiply by
0.5 for that when the compiler would convert to a shift?
> > it would be carefully chosen to produce an integer result;
>
> But what if scale is preserved?
My use of terminology without defining it was sloppy, sorry. In the
decimal context, I mean by 'integer' a decimal float whose exponent is 0.
(That is, the significand is the integer.) With the unnormalized decimal
float representation, that set of floats *is* the decimal integer 'type'
(a separate integer type, binary or decimal, is unnecessary). Hence the
scale being preserved is 0, which is what one wants.
> > anything which produced a result without an
> > exponent of 0 would always be more likely to give a non-zero
> > fraction that
> > .0, .00, .000, etc. -- and those non-zero ones would fail rapidly.
>
> Sorry, I didn't follow this ("that" should be "than"?).
Yes, 'than'. Was trying to answer in a 20-minute slot at airport -- I
should have waited ...
- - - - -
> > All I can say is that is has never been a problem in languages such as
> > Rexx and EXEC 2 which have had exactly that behaviour for almost 30
> > years.
> > I do not recall a single problem report about that behavior.
>
> I'm not familiar with Rexx, but my cursory reading of the Wikipedia
> article on it seems to indicate Rexx does not have arrays, but rather
> "compound variables" which have a different behavior and syntax. It
> seems to say that stem.1.0 implies simulation of a multidimentional
> array, not an array index with more precision (and similarly stem.
> 1.0.0). It also seems that stem..1 would not refer to the same
> location as stem.0.1 (perhaps it is a syntax error?).
They are essentially string-indexed arrays/vectors. The syntax is a bit
odd (square brackets were not available on all keyboards at the time) but
stem.foo.bar is effectively stem[foo, bar] where foo and bar are any
strings (and that syntax is allowed/used in NetRexx).
> I'm sure you know way more about Rexx than I do, but from basic
> research it seems that its array-like feature does not look or act
> like ECMAScript arrays, so I am not sure the experience is relevant. I
> think most people would expect behavior more like C or Java or Perl or
> Python arrays than like Rexx compound variables.
I think the ES arrays are very similar -- but I agree, when only integer
values are used, the arrays look like C arrays to many people (more on
this below in response to another comment).
- - - - -
Waldemar wrote:
> > This is, no doubt, because if one is treating array indexes as a set
of
> > integers you use integer operations on those indexes (almost
exclusively
> > +, -, and *).
>
> Mike;
>
> The claim that using only integers and only multiplication will save
array
> indexing is false. Under your current proposal exactly the same
problems
> occur even if you use exclusively integers. For example,
>
> a[10m*10m*10m*10m*10m*10m]
>
> and
>
> a[1e6m]
>
> refer to different array elements under your proposal.
The problem here was my ill-defined use of 'integer', sorry. 1e+6m is not
an 'integer' in the sense that I meant (although it has the same value as
one). If one uses only values of the form iiiiiim (where i is a digit,
not dot or 'e'), then multiplying them, adding them, subtracting them, or
using divideInteger on them will always result in an integer with exponent
0 -- a value of the same form. i.e., one can carry out conventional
'integer arithmetic' safely, and the results will be integers.
(divideInteger is an explicit integer-divide, but it can also be effected
by a regular divide and a quantize with appropriate rounding).
The result will also be an 'integer' for regular division of j/k if k is
an integer and j is a multiple of k (as would be the case when calculating
array indices).
- - - - -
Brendan summed up:
> Ignoring === as faux eq, the only issue here is d.toString() for decimal
d: should it preserve scale and stringify trailing zeroes and funny
exponents?
Are there any other cases like array indices where toString of a number is
used in a way such that "1.000" is materially different than "1"?
Certainly toString could reduce, and there could be a differently-spelled
operation to produce the 'nice' string, but the principle that toString
shows you exactly what you have got is a good one. (And it would be
goodness for ES to behave in the same way as other languages' toString for
decimals, too.)
In particular, when dealing with currency values, the number of decimal
places does correspond to the quantum (e.g., whether the value is cents,
mils, etc., and similarly for positive exponents, it indicates that one is
dealing in (say) $millions).
If the 'business logic' calculates a value rounded to the nearest cent
then the default toString will display that correctly without any
formatting being necessary (and if formatting were applied then if the
business logic were later changed to round to three places, the display
logic would still round to two places and hence give an incorrect result).
In short: the act of converting to a string, for display, inclusion in a
web page, etc., should not obscure the underlying data. If there's some
path in the logic that forgot to quantize, for example, one wants to see
that ASAP, not have it hidden by display formatting.
Mike
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
More information about the Es-discuss
mailing list