Proposal: 1) Number (integer or decimal) to Array 2) Array to Number (integer or decimal)

J Decker d3ck0r at gmail.com
Tue Mar 12 12:04:26 UTC 2019


The original code posted is not debugged.

input: 100.00015,
array:     [ 1, 0, 0, 0.0001, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 9, 7, 9, 5
],
araytoNum   100.05010000000497,

So given that you can't convert to and from a number, I'm sure everyone is
having a problem knowing how this conversion would work for useful work.
{ tests:
   [ 0,
     200,
     100.00015,
     -123,
     4.4,
     44.44,
     -0.01,
     123,
     2.718281828459,
     321.7000000001,
     809.56,
     1.61803398874989,
     1.999,
     100.01,
     545454.45,
     -7,
     -83.782,
     12,
     1.5,
     100.0001 ],
  arrays:
   [ [ 0 ],
     [ 2, 0, 0 ],
     [ 1, 0, 0, 0.0001, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 9, 7, 9, 5 ],
     [ -1, -2, -3 ],
     [ 4, 0.4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 ],
     [ 4, 4, 0.4, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 6 ],
     [ -0.01 ],
     [ 1, 2, 3 ],
     [ 2, 0.7000000000000001, 1, 8, 2, 8, 1, 8, 2, 8, 4, 5, 8, 9, 9, 9, 8 ],
     [ 3, 2, 1, 0.7000000000000001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 7,
6, 1 ],
     [ 8, 0, 9, 0.5, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 5, 4 ],
     [ 1, 0.6000000000000001, 1, 8, 0, 3, 3, 9, 8, 8, 7, 4, 9, 8, 9, 0, 1 ],
     [ 1, 0.9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 ],
     [ 1, 0, 0, 0.01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 1, 1, 2 ],
     [ 5, 4, 5, 4, 5, 4, 0.4, 4, 9, 9, 9, 9, 9, 9, 9, 9, 5, 3, 4, 3, 3, 9 ],
     [ -7 ],
     [ -8,
       -3,
       -6.999999999999999e-16,
       -8,
       -1,
       -9,
       -9,
       -9,
       -9,
       -9,
       -9,
       -9,
       -9,
       -9,
       -9,
       -9,
       -6,
       -2 ],
     [ 1, 2 ],
     [ 1, 0.5 ],
     [ 1, 0, 0, 0.0001, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 9, 6, 4 ] ],
  numbers:
   [ 0,
     200,
     100.05010000000497,
     -123,
     4.4,
     44.44,
     -0.01,
     123,
     2.718281828459,
     321.7000000001,
     809.56,
     1.6180339887498902,
     1.999,
     100.01000000000005,
     545454.45,
     -7,
     -83.082,
     12,
     1.5,
     100.00010000000331 ] }


On Mon, Mar 11, 2019 at 11:13 PM guest271314 <guest271314 at gmail.com> wrote:

> With respect, it's still not clear how you want to interact with the array
>> of values once you've destructured a Float into your array format.
>
> If all you have is an array of single-digit numbers that represent the
>> values in the tenths/hundredths/etc. positions of the source number, how
>> does this actually circumvent the challenges of representing Decimal values
>> that aren't exactly representable as a Float?
>
>
> It is not clear how your examples of adding specific values in JavaScript
> are relevant to the proposal.
>
> All of the test cases used at the code which fixed the bugs in the proof
> of concept at the original post output the expected result.
>
> If you have more test cases, number or decimal, to suggest for input
> relevant to the code at the original proposal, number to array, array to
> number, kindly post those tests cases listing input and expected output.
>
> The proposal does not seek to solve all JavaScript number issues.
>
> The proposal seeks to standardize the naming conventions of number to
> array and array to number, including decimals. An array is the simplest
> form of structured output. An object of key, value pairs (similar to
> Intl.NumberFormat, with JavaScript numbers instead of strings) can also be
> utilized for each of the digits of integer and decimal (fraction), if any.
>
>
>
> On Mon, Mar 11, 2019 at 4:33 PM Jeremy Martin <jmar777 at gmail.com> wrote:
>
>> With respect, it's still not clear how you want to interact with the
>> array of values once you've destructured a Float into your array format.
>>
>> If all you have is an array of single-digit numbers that represent the
>> values in the tenths/hundredths/etc. positions of the source number, how
>> does this actually circumvent the challenges of representing Decimal values
>> that aren't exactly representable as a Float?
>>
>> To illustrate this challenge, let's use the classic example we've all
>> seen hundreds of times:
>>
>> > .1 + .2
>> 0.30000000000000004
>>
>> For a long time, all the reading I would do about *why* this produced a
>> weird result would *sort* of make sense and *sort* of confuse me. That
>> is, I could understand *why* 3/10ths isn't representable as a Float, but
>> then I would get confused by the fact that I could type `.3` into a REPL,
>> and it would *actually work *(??!):
>>
>> > .3
>> 0.3
>>
>> I mean, who's lying? How come `.3` works fine when I just type it
>> straight in, and `.1 + .3` works just fine, but there's just these
>> specific cases like `.1 + .2` where all of a sudden `.3` decides not to
>> be representable again?
>>
>> I admit this is conjecture, but maybe that's part of the confusion
>> motivating this proposal? And maybe the idea is that if we can break `.1`
>> and `.2` into some sort of an array structure (e.g., [0, 1] and [0, 2]), then
>> we can add the individual parts as integers (giving us something like [0,
>> 3]) which we can then just convert back into a single numeric value at
>> the end as 0.3, and voila, no 0.30000000000000004 shenanigans?
>>
>> The problem is that this all builds on a fundamental misunderstanding of
>> what's going. Let's revisit the basic example of entering a value into the
>> REPL:
>>
>> > .3
>> 0.3
>>
>> This, as I stated earlier, contributed greatly to my own hangups in
>> understanding what was going on here. What I personally didn't understand
>> was that the `0.3` value you see above isn't actually the *Decimal*
>> value 0.3. It's just a *very* close approximation of 0.3. (so close, in
>> fact, that 0.3 is the *closest* Decimal value that it can be rounded to,
>> so that's what gets emitted).
>>
>> So, going back to our earlier example, why do we get a *different*
>> output when we're dealing with the result of a mathematical operation, as
>> opposed to getting the *same* very close approximation of 0.3 that we
>> get when we simply type it into the REPL?
>>
>> > .1 + .2
>> 0.30000000000000004
>>
>> The answer lies in the fact that 0.1 and 0.2 *also* can't be represented
>> exactly as Floats. Just like we saw with 0.3, we can type them into the
>> REPL and see a value that looks the exact same being emitted back at us:
>>
>> > .1
>> 0.1
>> > .2
>> 0.2
>>
>> ...but also like we saw with 0.3, they only *look* like accurate
>> representations. Once again, 0.1 and 0.2 are just the closest Decimal
>> values that the underlying Float values can be rounded to for display.
>>
>> This rounding behavior, then, is what causes us to get
>> 0.30000000000000004 when we add them together, because the *slight*
>> rounding error with 0.1 and the *slight* rounding error with 0.2
>> compound to result in a Float that no longer rounds closer to 0.3, and
>> instead closer to the "wrong" Decimal value that we see emitted before.
>>
>> It's worth noting that this same behavior applies to, e.g., 0.1 + 0.3, even
>> though that *looks* like it produces the correct result of 0.4. In
>> reality, however, this is just a case where the rounding errors have the
>> effect of (almost) canceling each other out, such that the resulting Float
>> rounds closer to 0.4 than any other value for display purposes (despite
>> being only negligibly more accurate than our 0.30000000000000004 result
>> was).
>>
>> Ok, so why am I trying to explain all this? Because I'm trying to
>> illustrate why it sounds like this proposal doesn't actually solve the
>> problem that you want it to. Is it possible to standardize a system for
>> transformations and math operations like the following?
>>
>>   const arg1 = numberToArray(0.1) // [0, 1]
>>   const arg2 = numberToArray(0.2) // [0, 2]
>>
>>   const arraySum = addArrayNumbers(arg1, arg2) // [0, 3]
>>
>>   const result = arrayToNumber(arraySum) // 0.3
>>
>> Sure, and at the very end, you actually get a value that *looks* right (
>> 0.3, yay!). But *it's still not actually 0.3.* So what become the
>> motivation for this? You have a solution that, in terms of memory and CPU
>> cycles, is orders of magnitude more costly to calculate than `0.1 + 0.2` as
>> a plain JavaScript expression, and in return you get a result that is, *at
>> best*, infinitesimally more accurate than the alternative when carried
>> all the way out to the quadrillionths place or greater.
>>
>> Do you actually have a use case for mathematical operations that are
>> fault tolerant enough to represent Decimal values as Floats, but that fault
>> tolerance is sensitive to very, very specific rounding behavior at the
>> quadrillionths level? I can't even imagine what that use case would be.
>>
>> On Mon, Mar 11, 2019 at 10:06 AM guest271314 <guest271314 at gmail.com>
>> wrote:
>>
>>> JS numbers are specified to be in terms of IEEE-754 doubles, so tenths,
>>>> hundredths, and so on cannot be precisely represented. [1] So there is no
>>>> way to increase precision here beyond the above that Tab showed, assuming
>>>> each of those operations are accurate to the bit.
>>>
>>>
>>> Not sure what the message is trying to convey?  The code at the first
>>> post already overcomes the issue of
>>>
>>>     i % 1 // 0.5670000000000073
>>>
>>> described by Tab. All of the input numbers are converted to array then
>>> back to number without losing any precision or adding more numbers to the
>>> input.
>>>
>>> The proposal suggests that each discrete digit of any number a user can
>>> get and set and be clearly defined with a consistent name, or reference.
>>> Converting the number to an array is a simple means of processing each
>>> digit independently.
>>>
>>> On Mon, Mar 11, 2019 at 10:41 AM Isiah Meadows <isiahmeadows at gmail.com>
>>> wrote:
>>>
>>>> JS numbers are specified to be in terms of IEEE-754 doubles, so tenths,
>>>> hundredths, and so on cannot be precisely represented. [1] So there is no
>>>> way to increase precision here beyond the above that Tab showed, assuming
>>>> each of those operations are accurate to the bit.
>>>>
>>>> [1]:
>>>> https://www.exploringbinary.com/why-0-point-1-does-not-exist-in-floating-point/
>>>> On Sun, Mar 10, 2019 at 13:26 guest271314 <guest271314 at gmail.com>
>>>> wrote:
>>>>
>>>>> So this would help with precision?
>>>>>
>>>>>
>>>>> To an appreciable degree, yes, without the scope of JavaScript
>>>>> floating-point number implementation.
>>>>>
>>>>> The gist of the proposal is to formalize, standardize, or whatever
>>>>> term specification writers want to use, the *naming* of each method or
>>>>> operation which can get and set each discrete digit of a number - without
>>>>> using String methods.
>>>>>
>>>>> For input
>>>>>
>>>>>     1234.567
>>>>>
>>>>> Each digit has a formal name which developers can get and set, whether
>>>>> in an array, object or number format.
>>>>>
>>>>> On Sun, Mar 10, 2019 at 5:17 PM Michael Theriot <
>>>>> michael.lee.theriot at gmail.com> wrote:
>>>>>
>>>>>> So this would help with precision?
>>>>>>
>>>>>> On Sunday, March 10, 2019, guest271314 <guest271314 at gmail.com> wrote:
>>>>>>
>>>>>>> (If you really wanted this as an integer, it's not well-founded; .567
>>>>>>>> isn't exactly representable as a double, so JS doesn't know that you
>>>>>>>> "meant" it to have only three digits after the decimal point, and
>>>>>>>> thus
>>>>>>>> want 567 as the answer. You'll instead get some very very large
>>>>>>>> integer that *starts with* 567, followed by a bunch of zeros,
>>>>>>>> followed
>>>>>>>> by some randomish digits at the end.)
>>>>>>>
>>>>>>>
>>>>>>> The code at the first post solves that problem.
>>>>>>>
>>>>>>> But the question is still "what would someone use this information
>>>>>>>> for?"
>>>>>>>
>>>>>>>
>>>>>>> That question has been answered several times in the posts above.
>>>>>>> This users' motivation was and is the ability to manipulate JavaScript
>>>>>>> floating-point numbers  (which could be considered "broken", as you
>>>>>>> described above) in order to solve mathematical problems (in this case,
>>>>>>> directly calculating the *n*th lexicographic permutation) with the
>>>>>>> number or decimal being represented as an array, without having to be
>>>>>>> concerned with not getting the same value when the array is converted back
>>>>>>> to a number.
>>>>>>>
>>>>>>> Felipe Nascimento de Moura mentioned several other applications.
>>>>>>>
>>>>>>> The work has already been done. This proposal is essentially to
>>>>>>> standardize the naming conventions. Whether a Number method is used
>>>>>>>
>>>>>>>     i.getTensMethod
>>>>>>>
>>>>>>> or an array is used
>>>>>>>
>>>>>>>    arr["integer"] // 1234
>>>>>>>
>>>>>>> or an object where values are arrays is used
>>>>>>>
>>>>>>>     o["fraction"] // .567
>>>>>>>
>>>>>>> Having mentioned Intl.NumberFormat earlier in the thread, if the
>>>>>>> issue devoting resources to a *new *proposal, Intl.NumberFormate
>>>>>>> can be extended; e.g. a rough draft in code
>>>>>>>
>>>>>>>     function formatNumberParts(args) {
>>>>>>>       return Object.assign({sign:0, fraction:[0], integer:[0]},
>>>>>>> ...args.filter(({type}) => type === "integer" || type === "fraction" ||
>>>>>>> type === "minusSign").map(({type, value}) => ({[type === "minusSign" ?
>>>>>>> "sign" : type]: type !== "minusSign" ? [...value].map(Number) : -1})));
>>>>>>>     }
>>>>>>>
>>>>>>>     let number = -123;
>>>>>>>
>>>>>>>     let formatter = new Intl.NumberFormat('en-US');
>>>>>>>
>>>>>>>     let res = formatter.formatToParts(number);
>>>>>>>
>>>>>>>     formatNumberParts(res);
>>>>>>>
>>>>>>> If the concern is that the proposal would not be useful, consider
>>>>>>> what you would *name* various uses of Math.trunc and remainder
>>>>>>> operator used at your message?
>>>>>>>
>>>>>>>
>>>>>>> On Sun, Mar 10, 2019 at 3:58 PM Tab Atkins Jr. <jackalmage at gmail.com>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> On Sat, Mar 9, 2019 at 11:10 AM Felipe Nascimento de Moura
>>>>>>>> <felipenmoura at gmail.com> wrote:
>>>>>>>> >
>>>>>>>> > Personally, I don't think it would be THAT useful...
>>>>>>>> > but...I think there is something behind this proposal that makes
>>>>>>>> sense.
>>>>>>>> >
>>>>>>>> > I do believe it could be useful for developers to have an easier
>>>>>>>> access to number parts or characteristics.
>>>>>>>> > Perhaps something like:
>>>>>>>> >
>>>>>>>> > const i = 1234.567;
>>>>>>>>
>>>>>>>> Can you provide a scenario in which these would do something useful,
>>>>>>>> such that it would be worth adding them over just using the math
>>>>>>>> operations that already exist?
>>>>>>>>
>>>>>>>> > console.log( i.float ); // 567
>>>>>>>>
>>>>>>>> i % 1
>>>>>>>>
>>>>>>>> (If you really wanted this as an integer, it's not well-founded;
>>>>>>>> .567
>>>>>>>> isn't exactly representable as a double, so JS doesn't know that you
>>>>>>>> "meant" it to have only three digits after the decimal point, and
>>>>>>>> thus
>>>>>>>> want 567 as the answer. You'll instead get some very very large
>>>>>>>> integer that *starts with* 567, followed by a bunch of zeros,
>>>>>>>> followed
>>>>>>>> by some randomish digits at the end.)
>>>>>>>>
>>>>>>>> > console.log( i.abs ); // 1234
>>>>>>>>
>>>>>>>> Math.trunc(i)
>>>>>>>>
>>>>>>>> > console.log( i.thousands ); // 1
>>>>>>>>
>>>>>>>> Math.trunc(i / 1000)
>>>>>>>>
>>>>>>>> > console.log( i.million ); // 0
>>>>>>>>
>>>>>>>> Math.trunc(i / 1e6)
>>>>>>>>
>>>>>>>> > console.log( i.hundred ); // 2
>>>>>>>>
>>>>>>>> Math.trunc(i / 100) % 10
>>>>>>>>
>>>>>>>> > console.log( i.hundreds ); // 12
>>>>>>>>
>>>>>>>> Math.trunc(i / 100)
>>>>>>>>
>>>>>>>> > console.log( i.ten ); // 2
>>>>>>>>
>>>>>>>> Math.trunc(i / 10) % 10
>>>>>>>>
>>>>>>>> > console.log( i.tens ); // 123
>>>>>>>>
>>>>>>>> Math.trunc(i / 10)
>>>>>>>>
>>>>>>>> > console.log( i.tenth ); // 5
>>>>>>>>
>>>>>>>> Math.trunc(i % 1 * 10) % 10
>>>>>>>>
>>>>>>>> > console.log( i.tenths ); // 5
>>>>>>>>
>>>>>>>> Math.trunc(i % 1 * 10)
>>>>>>>>
>>>>>>>> > console.log( i.hundredth ); // 6
>>>>>>>>
>>>>>>>> Math.trunc(i % 1 * 100) % 10
>>>>>>>>
>>>>>>>> > console.log( i.hundredths ); // 56
>>>>>>>>
>>>>>>>> Math.trunc(i % 1 * 100)
>>>>>>>>
>>>>>>>>
>>>>>>>> Some of these are easy to remember and use; others take some
>>>>>>>> thinking
>>>>>>>> to deploy. But the question is still "what would someone use this
>>>>>>>> information for?", such that the benefit to developers is worth the
>>>>>>>> cost to all parties involved (spec writers, implementors, testers,
>>>>>>>> and
>>>>>>>> then developers having to navigate a larger stdlib).
>>>>>>>>
>>>>>>>> ~TJ
>>>>>>>> _______________________________________________
>>>>>>>> es-discuss mailing list
>>>>>>>> es-discuss at mozilla.org
>>>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>>>
>>>>>>> _______________________________________________
>>>>>> es-discuss mailing list
>>>>>> es-discuss at mozilla.org
>>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>>
>>>>> _______________________________________________
>>>>> es-discuss mailing list
>>>>> es-discuss at mozilla.org
>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>
>>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>
>>
>> --
>> Jeremy Martin
>> 661.312.3853
>> @jmar777 <https://twitter.com/jmar777> / @j <https://stream.live/j>
>>
>> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190312/4bf69dbb/attachment-0001.html>


More information about the es-discuss mailing list