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

# guest271314 (5 years ago)

Original concept: Integer or decimal to array and array to decimal or integer codegolf.meta.stackexchange.com/a/17223

Proof of concept (with bugs)

function numberToArray(n) {
  if (Math.abs(n) == 0 || Math.abs(n) == -0) {
    return [n]
  }

  const r = [];

  let [
    a, int = Number.isInteger(a), d = g = [], e = i = 0
  ] = [ n || this.valueOf()];

  if (!int) {
    let e = ~~a;
    d = a - e;
    do {
      if (d < 1) ++i;
      d *= 10;
    } while (!Number.isInteger(d));
  }

  for (; ~~a; r.unshift(~~(a % 10)), a /= 10);

  if (!int) {
    for (; ~~d; g.unshift(~~(d % 10)), d /= 10);
    g[0] = g[0] * (1 * (10 ** -i))
    r.push(...g);
  }

  return r;
}

function arrayToNumber(a) {
  if ((Math.abs(a[0]) == 0 || Math.abs(a[0]) == -0) && a.length == 1) return a[0];
  const [
  g, r = x => x.length == 1
            ? x[0]
            : x.length === 0
              ? x
              : x.reduce((a, b) => a + b)
  , b = a.find(x => g(x)), p = a.findIndex(x => g(x))
  ] = [x => !Number.isInteger(x)];

  let [i, j] = [b ? p : a.length, -1];

  return a.length === 1
    ? a[0]
    : b && p
      ? r(a.slice(0, p).map(x => i ? x * (10 ** --i) : x))
      + (a[p] + (a[p + 1] !== undefined
        ? r(a.slice(p + 1).map(x => x * (10 ** --j)))
        : 0))
      : r(a.map(x => i ? x * (10 ** --i) : x))
}

    let 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.50, 100.0001];
    let arrays = tests.map(n => [...numberToArray(n)]);

    let numbers = arrays.map(n => arrayToNumber(n));

console.log({tests, arrays, numbers});

and working code (fixed bugs) by Stack Overflow user Shidersz stackoverflow.com/users/10366495/shidersz

Method numberToArray(): I have been working some time on your implementation, and thinked to first analyze the numberToArray() method. To start, I have decided to create a method for analyze a decimal number and return statistics about it, basically, the information you where getting from this part of your code:

if (!int) { let e = ~~a; d = a - e; do { if (d < 1) ++i; d *= 10; } while (!Number.isInteger(d)); }

The method I have made on is the next one (will be used inside numberToArray()) and basically gets the next information:

1) Integer section (iSection) of the decimal number (as integer).

2) Decimal section (dSection) of the decimal number (as integer).

3) Number of digits after the dot (dDigits).

4) Number of leading zeros after the dot (dZeros).

function getDecimalStats(dec){ let dDigits = 0, test = dec, factor = 1, dZeros = 0;

  // Store the integer section of the decimal number.

  let iSection = ~~dec;

  // Get the numbers of digits and zeros after the comma.

  while (!Number.isInteger(test))
  {
    factor = Math.pow(10, ++dDigits);
    test = dec * factor;
    dZeros += Math.abs(test - (iSection * factor)) < 1 ? 1 : 0;
  }

  // Store the decimal section as integer.

  let dSection = test - (iSection * factor);

  // Return an object with all statistics.

  return {iSection, dSection, dZeros, dDigits};
};

console.log(getDecimalStats(10.001));
console.log(getDecimalStats(-210.1));
console.log(getDecimalStats(-0.00001));

Of course, if you dislike, you can put this same logic directly inside numberToArray() method. So, after making the previous function, I have done some reorganization on your code and added some commentaries to helps me understand what you where doing. Finally, and after adapted your code, I have found that the wrong mapping to the arrays was mostly because the arithmetic precision when operating with float number. After investigate some time about this problem, I found a solution that is based using a mathematical correction factor (it is commented on the code when it is applied). All in all, and until this time, I have come with the next solution to the numberToArray() method.

function getDecimalStats(dec){ let dDigits = 0, test = dec, factor = 1, dZeros = 0;

  // Store the integer section of the decimal number.

  let iSection = ~~dec;

  // Get the numbers of digits and zeros after the comma.

  while (!Number.isInteger(test))
  {
    factor = Math.pow(10, ++dDigits);
    test = dec * factor;
    dZeros += Math.abs(test - (iSection * factor)) < 1 ? 1 : 0;
  }

  // Store the decimal section as integer.

  let dSection = test - (iSection * factor);

  // Return an object with all statistics.

  return {iSection, dSection, dZeros, dDigits};
};

function numberToArray(n){
  let r = [];

  if (Math.abs(n) == 0)
    return [n];

  let [a, int = Number.isInteger(a), g = []] = [n || this.valueOf()];

  // Get the stats of the decimal number.

  let {dSection, dZeros} = getDecimalStats(a);

  // Push the integer part on the array.

  for (; ~~a; r.unshift(~~(a % 10)), a /= 10);

  // Push the decimal part on the array.

  if (!int)
  {
    // Push decimal digits on temporal array "g".
    for (; ~~dSection; g.unshift(~~(dSection % 10)), dSection /= 10);

    // Define the correction factor for the next operation.
    let cf = 10 ** (++dZeros);

    // Map g[0] to a decimal number and push elements on the array.
    g[0] = (g[0] * cf) * ((10 ** -dZeros) * cf) / (cf * cf);
    r.push(...g);
  }

  return r;
}

let 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.50, 100.0001];
let arrays = tests.map(n => [...numberToArray(n)]);

console.log({tests, arrays});

Method arrayToNumber():

For this one I decided to go on my own (actually ignoring your current logic). The next approach will use the previously mentioned getDecimalStats() and mainly the Array::reduce() developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce :

function getDecimalStats(dec){ let dDigits = 0, test = dec, factor = 1, dZeros = 0;

  // Store the integer section of the decimal number.

  let iSection = ~~dec;

  // Get the numbers of digits and zeros after the comma.

  while (!Number.isInteger(test))
  {
    factor = Math.pow(10, ++dDigits);
    test = dec * factor;
    dZeros += Math.abs(test - (iSection * factor)) < 1 ? 1 : 0;
  }

  // Store the decimal section as integer.

  let dSection = test - (iSection * factor);

  // Return an object with all statistics.

  return {iSection, dSection, dZeros, dDigits};
};

function arrayToNumber(a) {
  // Get the index of the first decimal number.

  let firstDecIdx = a.findIndex(
    x => Math.abs(x) > 0 && Math.abs(x) < 1
  );

  // Get stats about the previous decimal number.

  let {dZeros} = getDecimalStats(firstDecIdx >= 0 ? a[firstDecIdx] : 0);

  // Normalize firstDecIdx.

  firstDecIdx = firstDecIdx < 0 ? a.length : firstDecIdx;

  // Reduce the array to get the number.

  let number = a.reduce(
    ({num, dIdx, dPow}, n, i) =>
    {
        // Define the correction factor.
        let cf = 10 ** (dPow + i - dIdx);

        if (i < dIdx)
           num += n * (10 ** (dIdx - i - 1));
        else if (i === dIdx)
           num = ((num * cf) + (n * cf)) / cf;
        else
           num = ((num * cf) + n) / cf;

        return {num, dIdx, dPow};
    },
    {num: 0, dIdx: firstDecIdx, dPow: ++dZeros}
  );

  return number.num;
}

let tests = [
  [0],
  [2, 0, 0],
  [1, 0, 0, 0.0001, 5],
  [-1, -2, -3],
  [4, 0.4],
  [4, 4, 0.4, 4],
  [-0.01],
  [1, 2, 3],
  [2, 0.7, 1, 8, 2, 8, 1, 8, 2, 8, 4, 5, 9],
  [3, 2, 1, 0.7, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  [8, 0, 9, 0.5, 6],
  [1, 0.6, 1, 8, 0, 3, 3, 9, 8, 8, 7, 4, 9, 8, 9],
  [1, 0.9, 9, 9],
  [1, 0, 0, 0.01],
  [5, 4, 5, 4, 5, 4, 0.4, 5, 0],
  [-7],
  [-8,-3, -0.7, -8, -2],
  [1, 2],
  [1, 0.5],
  [1, 0, 0, 0.0001]];
let numbers = tests.map(n => arrayToNumber(n));

console.log(numbers);

Finally, I hope you can value my efforts, and obviously there can be a lot of improvements to my solution (so, any recommendation is welcome). For example, there are currently none or few checks for safety.

Number (integer or decimal) to array, array to number (integer or decimal) without using strings stackoverflow.com/q/54433007

Context and use cases:

BigInt developers.google.com/web/updates/2018/05/bigint is available in some browsers, though not a BigDecimal. The conversion from integer or decimal to array and array to integer or decimal should be possible using the JavaScript programming language. The input and output should not need to be converted to a string during the procedure.

Ability to adjust nth digit of an integer or decimal by adjusting decimal or integer at nth index of array, to try to solve OEIS A217626 oeis.org/A217626 directly, for example

~~(128.625*9*1.074)//1243
~~(128.625*9*1.144)//1324

where the decimal portion can be manipulated by referencing the index of an array, then converting the array back to a number.

Specification (WIP):

[...Math.E] -> [2, 0.7, 1, 8, 2, 8, 1, 8, 2, 8, 4, 5, 9] -> 2.718281828459

Input <----------> Output

-123               [-1,-2,-3]
4.4                [4,0.4]
44.44              [4,4,0.4,4]
-0.01              [-0.01]
123                [1,2,3]
200                [2,0,0]
2.718281828459     [2,0.7,1,8,2,8,1,8,2,8,4,5,8,9]
321.7000000001     [3,2,1,0.7,0,0,0,0,0,0,0,0,1]
809.56             [8,0,9,0.5,6]
1.61803398874989   [1,0.6,1,8,0,3,3,9,8,8,7,4,9,8,9]
1.999              [1,0.9,9,9]
100.01             [1,0,0,0.01]
545454.45          [5,4,5,4,5,4,0.4,5]
-7                 [-7]
-83.782            [-8,-3,-0.7,-8,-2]
1.5                [1,0.5]
100.0001           [1,0,0,0.0001]
# Jeremy Martin (5 years ago)

Can you explain the motivation for this proposal?

At first blush, this seems like an incredibly arbitrary pair of value conversion utilities. Are there real world applications for this?

# guest271314 (5 years ago)

The original motivation was trying to solve OEIS A217626 directly, that is, without generating all of the permutations, specifically, using only a multiple of 9 (TL;DR How to improve efficiency of algorithm which generates next lexicographic permutation? stackoverflow.com/questions/43290467/how-to-improve-efficiency-of-algorithm-which-generates-next-lexicographic-permut continued from SO user chqrlie 's answer stackoverflow.com/a/34238979 at Permutations without recursive function call stackoverflow.com/q/34013675; 9erilous 9ermutations codegolf.stackexchange.com/questions/175693/9erilous-9ermutations) directly (mathematically, without using any loop, and overcoming JavaScript floating-point issues). See proposal at

Ability to adjust nth digit of an integer or decimal by adjusting decimal or integer at nth index of array, to try to solve OEIS A217626 oeis.org/A217626 directly, for example

~~(128.625*9*1.074)//1243
~~(128.625*9*1.144)//1324

where the decimal portion (.074; .144, respectively) can be manipulated by referencing the index of an array, then converting the array back to a number.

# guest271314 (5 years ago)

See above

# Naveen Chawla (5 years ago)

What is the real world use case, presuming it's not just an academic exercise

# guest271314 (5 years ago)

Not sure what you mean by "real world" use case. Described at least one use case at the proposal. Statistics; graphs; mathematics; number (integer and decimal) manipulation using indexes of arrays with ability to convert manipulated array back to number and vice versa.

For example, if the requirement is to add or subtract the nth digit of 3.141592653589793, the irrational number can be converted to an array, then the nth decimal can be added or subtracted, if necessary, manipulation can also be performed on the adjacent indexes of the array, then the array can be converted back to a JavaScript number.

# Jeremy Martin (5 years ago)

By "real world" we mean somewhere outside of a code challenge or similarly low utility program context.

You mentioned statistics, for example. Can you reference a specific example from that domain where these methods would offer an advantage?

# guest271314 (5 years ago)

Cited a specific example at the proposal itself, and at the first response. From own experience trying to solve OEIS A217626 oeis.org/A217626 directly. Kindly re-read the original proposal and subsequent email to this list.

It is simpler to have the ability to add, subtract, divide, or otherwise manipulate individual nth indexes of an integer or decimal represented as an array of integers potentially containing one decimal than trying to perform the same mathematical operations on a number in JavaScript (essentially broken in JavaScript due to the floating-point number issues).

Will re-post a use case, again, which is included at the original proposal relevant to trying to solve for the nth permutation, or combination, directly (without using loops)

~~(128.625*9*1.074)//1243
~~(128.625*9*1.144)//1324 

where if the requirement is to increment the decimal portion of 1.074 or 1.144 if the decimal is first converted to an array, we can use array methods to tests the matches we are looking for. For example,

[1.0, 7, 4]

representation of 1.074 allows each of the portions of the number to be adjusted independently.

If the expected result is

 1.085

we can use bracket notation

 arr[1] = arr[1] + 1
 arr[2] = arr[2] + 1

Since we have previously defined a .toNumber() Array method we know we can get the value of the array as a JavaScript number.

 let n = arr.toNumber() // 1.085

The same is true for

 128.625

where that decimal as well can be manipulated as an array, converted to number and further mathematical operations can be performed with the 1.074 portion of the mathematical procedure.

If we are trying to find needles in haystacks for several million matches, for example, combinatorics, permutations - using only numbers to do so, ignoring the values - then manipulating arrays, for example, from 1.0 to 1.NNNNNNNNNN where each N can be represented as an index of an array provides greater flexibility and control over the manipulation of the decimal than relying on JavaScript Number or Math, or Number to String back to Number operations.

Perhaps BigDecimal could address some of the issues, though the array approach allows individual digits manipulation for each digit of the array/number directly.

Posted the proposal here for your consideration.

Am not really interested in lobbying for the proposal within the context of overcoming conjecture, etc.; though can and will answer questions relevant to own experiences trying to work with integers and decimals in JavaScript.

Either people here will get the usefulness of such methods relevant to math or the people here will not. Either outcome is fine. All can do is post the proposal here. The code at the linked answer already works, to it is not a "coding challenge".

# Steve Fink (5 years ago)

Any addition to the JavaScript language needs to (1) be motivated by a use case encountered by a large number of users, (2) cannot be implemented in a straightforward and reliable way by a library, (4) is implementable by a JS implementation without undue trouble, and (4) does not conflict with other parts of the language.

For your proposal:

(1) - absolute fail (2) - arguable (3) - uncertain, depends on exact semantics (4) - pass

Unless you can somehow prove that a large numbers of users give a rat's hindquarters about things that this would enable, this is a nonstarter.

It would be useful to have a FAQ somewhere with a version of the above 4 rules that is better worked out and justified, so we could point to that. (From whatever public-facing forum is selected for the future; this one is dead.)

# Jeremy Martin (5 years ago)

It's entirely possible that I'm being thick here, but can you expand on the use case?

  • The initial link that you posted results in a code challenge that was voted down to a negative score as a result of ambiguity in the challenge description, and...
  • the two expressions you provided are already valid JavaScript.
  • I'm also confused as to why we'd want 1.074 to convert to [1.0, 7, 4]. How is that different from, say, 1.74 also converting to [1, 7, 4] (given that 1 == 1.0)?

Going back to our request for a "real world" use case, we're asking you to provide an example of something that you'd want to do that has value external to the proposal itself. That is, if I proposed a toX() method that always converted the receiver to the character "X", I would need to provide a real world justification beyond "it's easier to convert things into the letter X". So, again, what is a real world utility of this transformation?

# guest271314 (5 years ago)

Cannot get into "a large number of users" heads. Again, am not interested in overcoming conjecture. If the proposal does not meet you folks' criteria, so be it.

# guest271314 (5 years ago)

Am not concerned with "down" votes. Do not really care about "up" or "down" votes. Would only object directly to censorship which unfortunately, is (hypocritically) practiced from top-down (CEO; management; moderators; "trusted user"; etc.) at the linked sites (full disclosure for your own edification english.meta.stackexchange.com/questions/12046/is-using-colored-girls-as-an-incidental-example-offensive-or-unwelcoming ; embed.plnkr.co/5CwKsW/; "This account is temporarily suspended network-wide. The suspension period ends on Feb 28 '24 at 16:20."; twitter.com/guest271314/status/1102254119161491456). That is beyond the scope of this proposal. Nonetheless, have posted questions and answers at those sites, before being censored, thus the links provided.

The proposal states the specification is WIP. Handing leading 0's at decimal portion of number was a challenge faced when initially conceived the proof of concept. Which was solved by the answer at the SO post which fixed the two bugs described at the question at SO. Therefore, there is working code which can convert Number <--> Array, and spread a Number [...Math.PI].

The 1.0 is not a proper example, though illustrates the problems with JavaScript number implementation. An appropriate example would be 1.1. That is, a standardized way to represent a decimal as an array.

Have already described a "real world" example, at least twice above, citing the original proposal. If you do not see that as a "real world" example, am not interested in trying to convince you, or anyone else of that "real world" example.

What will more than likely eventually occur is that your "community" will ban this user after presenting evidence, as am not beholden to you or your views, and have no need to fit into to your "community". Am well-suited to solving own problems. Share when have a notion that what have experimented with may be of interest to others; e.g., stackoverflow.com/questions/47119426/how-to-set-file-objects-and-length-property-at-filelist-object-where-the-files-a ; guest271314/SpeechSynthesisSSMLParser.

Just posted the proposal to you here for your consideration. If the proposal is not useful, then disregard and return to your important affairs that you have deemed useful to your time.

# J Decker (5 years ago)

On Thu, Mar 7, 2019 at 2:55 PM guest271314 <guest271314 at gmail.com> wrote:

Cannot get into "a large number of users" heads. Again, am not interested in overcoming conjecture. If the proposal does not meet you folks' criteria, so be it.

On Thu, Mar 7, 2019 at 10:46 PM Steve Fink <sphink at gmail.com> wrote:

Any addition to the JavaScript language needs to (1) be motivated by a use case encountered by a large number of users, (2) cannot be implemented in a straightforward and reliable way by a library, (4) is implementable by a JS implementation without undue trouble, and (4) does not conflict with other parts of the language.

For your proposal:

(1) - absolute fail (2) - arguable (3) - uncertain, depends on exact semantics (4) - pass

Unless you can somehow prove that a large numbers of users give a rat's hindquarters about things that this would enable, this is a nonstarter.

It would be useful to have a FAQ somewhere with a version of the above 4 rules that is better worked out and justified, so we could point to that. (From whatever public-facing forum is selected for the future; this one is dead.)

On 3/7/19 2:22 PM, guest271314 wrote:

Have you read the proposal, and the first response to your inquiry? It is simpler to have the ability to add, subtract, divide, or otherwise manipulate individual nth indexes of an integer or decimal represented as an array of integers potentially containing one decimal than trying to perform the same mathematical operations on a number in JavaScript (essentially broken in JavaScript due to the floating-point number issues).

Will re-post a use case, again ~~(128.62591.074)//1243 ~~(128.62591.144)//1324 where if the requirement is to increment the decimal portion of 1.074 or 1.144 if the decimal is first converted to an array, we can use array methods to tests the matches we are looking for. For example, [1.0, 7, 4] representation of 1.074 allows each of the portions of the number to be adjusted independently. Since we have previously defined a .toNumber() Array method we know we can get the value of the array as a JavaScript number.

On Thu, Mar 7, 2019 at 10:12 PM Jeremy Martin <jmar777 at gmail.com> wrote:

By "real world" we mean somewhere outside of a code challenge or similarly low utility program context.

You mentioned statistics, for example. Can you reference a specific example from that domain where these methods would offer an advantage?

On Thu, Mar 7, 2019, 5:05 PM guest271314 <guest271314 at gmail.com> wrote:

Not sure what you mean by "real world" use case. Described at least one use case at the proposal. Statistics; graphs; number and integer manipulation using indexes of arrays with ability to convert manipulated array back to number.

On Thu, Mar 7, 2019 at 9:56 PM Naveen Chawla <naveen.chwl at gmail.com> wrote:

What is the real world use case, presuming it's not just an academic exercise

On Thu, 7 Mar 2019, 9:08 pm guest271314, <guest271314 at gmail.com> wrote:

Ability to adjust nth digit of an integer or decimal by adjusting decimal or integer at nth index of array, to try to solve OEIS A217626 oeis.org/A217626 directly, for example ~~(128.62591.074)//1243 ~~(128.62591.144)//1324 where the decimal portion can be manipulated by referencing the index of an array, then converting the array back to a number.

On Thu, Mar 7, 2019 at 8:55 PM Jeremy Martin <jmar777 at gmail.com> wrote:

Can you explain the motivation for this proposal?

At first blush, this seems like an incredibly arbitrary pair of value conversion utilities. Are there real world applications for this?

On Thu, Mar 7, 2019 at 3:43 PM guest271314 <guest271314 at gmail.com> wrote:

---------- Forwarded message --------- From: guest271314 <guest271314 at gmail.com> Date: Thu, Mar 7, 2019 at 8:35 PM Subject: Proposal: 1) Number (integer or decimal) to Array 2) Array to Number (integer or decimal) To: <es-discuss at mozilla.org>

Original concept: Integer or decimal to array and array to decimal or integer codegolf.meta.stackexchange.com/a/17223

Proof of concept (with bugs)

function numberToArray(n) {

if (Math.abs(n) == 0 || Math.abs(n) == -0) { return [n] }

const r = [];

let [ a, int = Number.isInteger(a), d = g = [], e = i = 0 ] = [ n || this.valueOf()];

if (!int) { let e = ~~a; d = a - e; do { if (d < 1) ++i; d *= 10; } while (!Number.isInteger(d)); }

for (; a; r.unshift((a % 10)), a /= 10);

if (!int) { for (; d; g.unshift((d % 10)), d /= 10); g[0] = g[0] * (1 * (10 ** -i)) r.push(...g); }

return r; } function arrayToNumber(a) { if ((Math.abs<span class="gmail-m_2662878951066317968m_7497912379499730396gmail-m_-49591865513921258gmail-m_191674293613409874m_-1290191079188355796gmail-pun" style="margin:0px;padding:0px;border:0px;font-style:inherit;font-variant:inherit;font-weight:inherit;font-stretch:inherit;line-height:inherit;font-family:inherit;

Really though that the above would be simpler to implement. The example code doesn't even function correctly but...

like 'numberTOArray(n)' would just be something like [... n.toString()].slice(1).map( (c,i)=>-1*(c.codePointAt(0)>=0x30?(c.codePointAt(0)-0x30): ((d=i),0)) )

; but then going to read the original message I see it's actually quite convoluted.

(it has an error of getting a trailing ... 0000000000000001 which causes the reverse to fail shrug )

function numberTOArray(n) { var d = -1; // decimal location var r; if( n < 0 ) r = [... n.toString()].slice(1).map( (c,i)=>-1*(c.codePointAt(0)>=0x30?(c.codePointAt(0)-0x30): ((d=i),0)) )

else r = [... n.toString()].map( (c,i)=>c.codePointAt(0)>=0x30?(c.codePointAt(0)-0x30):((d=i),0) )

var de = 0; // end of decimal leading 0's for( de = d; de < r.length; de++ ) if( r[de] != 0 ) break; r[d] = r[de] * Math.pow(10, (d-de)); r.splice( d+1, (de-d) ); return r; }

function arrayTONumber(n) { var str; var d = -1; if( n[0]< 0 ) { str = n.map( (n,i)=>(n==0|| (n>=1 || n<=-1))?String.fromCodePoint( 0x30 + -n ):((d=i),'.') ).reduce( (acc,val)=>acc+val,'' );

if( d>=0 ) {

str = str.substring(0,d+1) + n[d].toString().substring(2) + str.substring(d+1); } return -Number(str); } else { str =n.map( (n,i)=>(n==0|| (n>=1 || n<=-1))?String.fromCodePoint( 0x30 + n ):((d=i),'.') ).reduce( (acc,val)=>acc+val,'' );

if( d>=0 ) {

str = str.substring(0,d+1) + n[d].toString().substring(2) + str.substring(d+1); } return Number(str); } }

But ya; don't see a very general purpose in such a thing...

# guest271314 (5 years ago)

FWIW the original requirement included a self-imposed restriction of converting the input to a String at any point during the procedure, in part to illustrate the ("broken") JavaScript Number/Math implementations.

If you have a "simpler" implementation to the requirement, then post your answer at SO. Am banned for 5 years - a few days, though will still be able to view your answer. Or, post a gist.

Yes, to settle the matter of a lot of users having a need for such an implementation, can only speak for self. Have tried to solve the linked OEIS A217626 oeis.org/A217626 for several years now - directly. That is, specifically, using only a multiple of the number 9 to get any nth permutation. That is how arrived at making this proposal here.

# Gus Caplan (5 years ago)

this seems like a solution in search of a problem.

if you want to add a number in a specific place, you can just multiply it by that place. e.g. increasing the tenths place by 2 is n + (2 / 10), and increasing the tens place is n + (2 * 10).

# guest271314 (5 years ago)

That still leaves determining how many digits there are after the decimal point and where the number added sums to greater than 10 carrying over the remainder to the adjacent digits, if needed, which is simpler using array methods where the .length after the index where the single decimal is located in the array will provide the 10's, 100's, etc.

If alternative solutions provide the expected results, without standardization, simply disregard this proposal. The proposal is intended to standardize the conversion from number to array and array to number.

Consider the examples at the proposal, where several generator functions can be used in parallel to adjust both 128.625 and 1.074 through and beyond 1.144, where for example, input is "abcdefghi", we ignore the values and permute only the indexes as a whole number and match the multiples of 9 which meet the necessary criteria.

In any event, do with the proposal as you will.

# Isiah Meadows (5 years ago)

@guest When making a language proposal, the first thing that should be on your mind isn't "it'd be nice if ...", but the problems you're trying to solve. And these problems can't just be simple toy problems like a code golf challenge - they have to be real-world problems in code you write for sites, apps, libraries, and so on. If it's so niche as to be useless outside a simple challenge, you're unlikely to get any sort of support for adding it.

Also, when making a language proposal, it's your responsibility to persuade others of its usefulness. It's not others' responsibility to dispute it - they could just as easily ignore it and your proposal won't have a chance to be merged into the spec. You have to be the one to explain why it should be added.


Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com

# guest271314 (5 years ago)

@guest When making a language proposal, the first thing that should be on your mind isn't , but the problems you're trying to solve. And these problems can't just be simple toy problems like a code golf challenge - they have to be real-world problems in code you write for sites, apps, libraries, and so on. If it's so niche as to be useless outside a simple challenge, you're unlikely to get any sort of support for adding it. Also, when making a language proposal, it's your responsibility to persuade others of its usefulness. It's not others' responsibility to dispute it - they could just as easily ignore it and your proposal won't have a chance to be merged into the spec. You have to be the one to explain why it should be added.

What part of the proposal, in your view, did not read "it'd be nice if ..." number to array <--> array to number specification and standardization?

Not sure what you mean by "toy problems"? Do you mean only concepts that meet your "toy" interests? Scale is irrelevant. The real world problem is standardization of number to array, array to number conversion in JavaScript. The use case for this user has been stated several times above: manipulation of numbers as arrays with the standardization of what to expect - in JavaScript code output - when array is converted back to number or decimal to the maximum JavaScript can produce. That is obviously not a compelling reason for users here. So what? Made the proposal anyway, without having any expectation as to the outcome.

# Isiah Meadows (5 years ago)

What part of the proposal, in your view, did not read "it'd be nice if ..." number to array <--> array to number specification and standardization?

I think you missed my point in the first sentence. I'm saying the first thing on your mind when creating proposals shouldn't be "it'd be nice if ...". Please re-read that first sentence and you'll get what I'm saying.

Not sure what you mean by "toy problems"? Do you mean only concepts that meet your "toy" interests? Scale is irrelevant. The real world problem is standardization of number to array, array to number conversion in JavaScript.

  1. Scale is mostly irrelevant here, even in my criticism. The only requirement here is that it's in code you'd actually write when building something. Code golf challenges aren't sufficient, since JS doesn't optimize for that. It needs to be something genuinely useful, useful enough to merit the added engine complexity as a result.
  2. Not everyone agrees the problem even exists - in fact, most of us don't. "Number to array" is as simple as defining a Symbol.iterator method on Number.prototype and using [...num]. "Array to number" is just +[...values], which evaluates to Number(String([...values])).

Isiah Meadows contact at isiahmeadows.com, www.isiahmeadows.com

# guest271314 (5 years ago)

Not sure if your failure thus far to gather what the proposal is actually suggesting is based on your limited experimentation in using numbers in JavaScript, or some other reason. That is ok. Your second point illustrates the problem faced. Where your pseudo code uses String methods. That should not be necessary. Further, where in the resulting array are you separating the decimal portion of the number? How do you convert a decimal or irrational number to JavaScript numbers in an array, accounting for the decimal? None of those inquiries have standardized answers. You folks write standards. Only asked the question on coding sites to not solely rely on own approach to solving the inquiry, which ordinarily achieve before asking the question.

It is not a "homework" project. Again, have no issues solving own coding problems. It is not a coding challenge. It is a proposal to standardize conversion of number to array <--> array to number. If you want to include "ranges" in the proposal, have composed code for that output as well. The issue is consistency (is an individual were to have such expectations) of output in conversion in each of array to number and number to array. Am not concerned with what you refer to as "apps", that is your business. The proposal is for standardization of handling decimals to and from an array.

That is obviously not a concern for you, or users here.

# Augusto Moura (5 years ago)

There is space for improvement in low level programming in Javascript, sure isn't the main focus of the language, but I don't think unobtrusive proposals should be a problem. There's a lot of C/C++ number apis that would be really useful in some use cases (I'm thinking now in matrix operations, graphics and games).

There's any prior art/work in your idea? Any C or other languages functions, any spec'd norm (IEEE, ISO)? Or any library implementing it that got popular in a niche? Having any examples of implementations (aside for your own of course) would help your proposal immensely. I'm not being toxic here this is a really specific use-case that I know almost nothing.

About users not being concerned with your problem, we have to be really cautious when supporting proposals, we can't just add every function and syntax that solves someone problems, the language would became bloated and complex rapidly. There's a fantastic thread [1] that explains the point a lot better than me and you should definitely read it.

Don't be angered if we don't give a lot of reception for your first proposal, you can always improve your idea or get a new one.

Em qui, 7 de mar de 2019 às 21:56, guest271314 <guest271314 at gmail.com> escreveu:

# guest271314 (5 years ago)

There's any prior art/work in your idea? Any C or other languages functions, any spec'd norm (IEEE, ISO)? Or any library implementing it that got popular in a niche? Having any examples of implementations (aside for your own of course) would help your proposal immensely. I'm not being toxic here this is a really specific use-case that I know almost nothing.

There is prior art relevant to determining where the decimal portion of a number is, which is linked at the SO question. AFAIK there is no prior art relevant to the full conversion from number to array and array to number, including decimal numbers.

The proposal does not ask for code to solve the problem. The proposal asks for this body to consider standardizing the procedure in a specification.

For example, given input the number e 2.718281828459045, could be represented in an array in several different manners

[2, .718281828459045]

[2.7, 18281828459045]

[2, 0.7, 1, 8, 2, 8, 1, 8, 2, 8, 4, 5, 9]

And there is also the case of negative integer and negative decimal representations. These different representations of numbers in an array could be given appropriate names for disambiguation, by a standardization body. From perspective here the last representation provides the most flexibility, though the others could be useful for different applications.

About users not being concerned with your problem, we have to be really cautious when supporting proposals, we can't just add every function and syntax that solves someone problems, the language would became bloated and complex rapidly. There's a fantastic thread [1] that explains the point a lot better than me and you should definitely read it. Don't be angered if we don't give a lot of reception for your first proposal, you can always improve your idea or get a new one.

Whether this body decides to move forward addressing the matter or not is your decision.

Am not "angered". The responses are simply conjecture; western academic SOP. Address such conjecture routinely in all fields of endeavor; from history to biology to physics to law; et al. etc., without rancor. Do not care one way or the other, as am not a disciple of or enamored with that or any other regime. Brought this to tc39 attention once examples of working code were completed. Do or do not do what thou wilst.

# Jeremy Martin (5 years ago)

Is it fair to suggest that transforming numeric values to and from arrays isn't the ultimate goal of this proposal? Based on your examples, it seems there are specific manipulations you would like to be able to perform to numeric values, and your contention is that these manipulations would be more straightforward if various components of that value (i.e., the individual digits, the decimal location, and the sign) were represented in a "more structured" way (i.e., an array). Is that much a fair assessment?

If that's the case, could you expand on the specific manipulations themselves? Preferably something more explicit and scoped than linking out to one of these external references, if possible.

# guest271314 (5 years ago)

Is it fair to suggest that transforming numeric values to and from arrays isn't the ultimate goal of this proposal?

That is a fair assessment.

Based on your examples, it seems there are specific manipulations you would like to be able to perform to numeric values, and your contention is that these manipulations would be more straightforward if various components of that value (i.e., the individual digits, the decimal location, and the sign) were represented in a "more structured" way (i.e., an array). Is that much a fair assessment?

Yes, that is also a fair assessment. Developers in the wild can call the procedure whatever they want right now and will not be incorrect, as no specification or standard defines the procedure or the possible outputs. Specification composition for JavaScript language is what this body is allegedly about, correct?

The code for "transforming" numeric values to array and array to numeric value has at least one complete implementation. The goal of this proposal is not asking for code to achieve the requirement.

The goal of this proposal is to suggest to this body to take up the task of defining the various manners in which that transformation can be achieved, as illustrated at the example for the number e at esdiscuss.org/topic/fwd-proposal-1-number-integer-or-decimal-to-array-2-array-to-number-integer-or-decimal#content-21 .

From perspective here, the third example provides the output (in array representation) which can be manipulated more extensively than the previous two examples.

[2, .718281828459045] // example 1

[2.7, 18281828459045] // example 2

[2, 0.7, 1, 8, 2, 8, 1, 8, 2, 8, 4, 5, 9] // example 3

Note, a 4th possible output, using the approach at esdiscuss.org/topic/fwd-proposal-1-number-integer-or-decimal-to-array-2-array-to-number-integer-or-decimal#content-18, without any other modifications, would result in

["2", ".", "7", "1", "8", "2", "8", "1", "8", "2", "8", "4", "5", "9"]

An additional perspective

just a thought how about 123.001 being represented as [[1,2,3],[0,0,1]] and I may be missing the point I suppose but could extend that to 123.001 -> [[1],[1,2,3],[0,0,1]] and -123.001 -> [[0],[1,2,3],[0,0,1]] where [[Modifier],[Int],[Decimal]] – Bibberty Jan 30 at 3:53 stackoverflow.com/questions/54433007/number-integer-or-decimal-to-array-array-to-number-integer-or-decimal-witho#comment95675757_54433007

How should those three (or four, including the String conversion method that was specifically and explicitly avoided during own experimentation, for several reasons, including but not limited to, again, consistency; and having to convert each element or index of the Array to a Number to further process or (re-)modify the output; and the "cost" of String conversion re calculation of .length; to illustrate that JavaScript floating-point numbers are still "broken", in the absence of a BigDecimal; etc.) examples be named for disambiguation as to the output?

If this body does decide to take up the matter of actually defining Number and/or Math, and Array methods to perform the conversions, it would be helpful if each of the three (and potentially more) possible outputs have a clearly defined name for that output. Also, representation of negative integers and decimals (the "sign" of an integer or decimal) could be addressed; e.g.,

Input/Output <---> Output/Input

-123               [-1,-2,-3]

Goal: For consistency and uniformity as to what the output is, to avoid confusion. If you folks want to take up the coding part relevant to adding methods to Number and/or Math and Array, that is fine. Though that is not the gist of this proposal. The proposal suggests that the outputs should be specified in a clear manner.

AFAIK, there is no prior art relevant to conversion or "transforming" JavaScript numeric values to array and array to numeric values. The closest that can cite is Intl.NumberFormat.prototype.formatToParts tc39.github.io/ecma402/#sec-Intl.NumberFormat.prototype.formatToParts. the resulting object contains values that are strings, and not expanded, or spread, to an array similar to example 3. Also, there is no standard for the procedure in code; and no standard for how the various possible outputs are named. E.g., how does a developer differentiate between the output at example 1 from the output at example 3, by convention, or common name?

Does the above make sense to you relevant to the purpose of this proposal and what this proposal actually suggests?

# Naveen Chawla (5 years ago)

I've probably missed it, but what application are you building that would use this feature? Or, under what circumstances would an application use this feature?

# Felipe Nascimento de Moura (5 years ago)

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;

console.log( i.float ); // 567 console.log( i.abs ); // 1234 console.log( i.thousands ); // 1 console.log( i.million ); // 0 console.log( i.hundred ); // 2 console.log( i.hundreds ); // 12 console.log( i.ten ); // 2 console.log( i.tens ); // 123 console.log( i.tenth ); // 5 console.log( i.tenths ); // 5 console.log( i.hundredth ); // 6 console.log( i.hundredth ); // 56

There is this table with some patterns: Large Numbers Number.................... Name Symbol Description (Short Scale) Description (Long Scale) 1,000,000,000,000,000,000,000,000 yotta Y Septillion Quadrillion 1,000,000,000,000,000,000,000 zetta Z Sextillion Thousand Trillion/Trilliard 1,000,000,000,000,000,000 exa E Quintillion Trillion 1,000,000,000,000,000 peta P Quadrillion Thousand Billion/Billiard 1,000,000,000,000 tera T Trillion Billion 1,000,000,000 giga G Billion Thousand Million/Milliard 1,000,000 mega M Million Million 1,000 kilo k Thousand Thousand 100 hecto h Hundred Hundred 10 deca da Ten Ten>Small Numbers Number.................... Name Symbol Description (Short Scale) Description (Long Scale) 0.1 deci d Tenth Tenth 0.01 centi c Hundredth Hundredth 0.001 milli m Thousandth Thousandth 0.000 001 micro u Millionth Millionth 0.000 000 001 nano n Billionth Thousand Millionth 0.000 000 000 001 pico p Trillionth Billionth 0.000 000 000 000 001 femto f Quadrillionth Thousand Billionth 0.000 000 000 000 000 001 atto a Quitillionth Trillionth 0.000 000 000 000 000 000 001 zepto z Sextillionth Thousand Trillionth 0.000 000 000 000 000 000 000 001 yocto y Septillionth Quadrillionth I mean...something like that could make sense to offer faster access to parts of numbers...

  • Could be useful for games, statics, animations, transitions, etc
  • Very useful to deal with the recently added bigInt
  • The implementation of something like this is not trivial, and there must be many different ways to accomplish similar results, what increases the granularization of implementations in different libs
  • I don't think this would bring trouble to current language implementation

Just adding my 2 cents to the discussion :)

[ ]s

--

Felipe N. Moura Web Developer, Google Developer Expert developers.google.com/experts/people/felipe-moura, Founder of

BrazilJS braziljs.org and Nasc nasc.io.

Website: felipenmoura.com / nasc.io Twitter: @felipenmoura twitter.com/felipenmoura

Facebook: fb.com/felipenmoura LinkedIn: goo.gl/qGmq

Changing the world is the least I expect from myself!

# Tab Atkins Jr. (5 years ago)

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).

# guest271314 (5 years ago)

(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 nth 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. Since the graph of using only the indexes of an array or string represented as a whole number and being a multiple of 9 is not linear (tl;dr How to improve efficiency of algorithm which generates next lexicographic permutation? stackoverflow.com/q/43290467)

// graph 1
0,9,81

// graph 2
abc 012 0
acb 021 1 9
bac 102 2 81
bca 120 3 18
cab 201 4 81
cba 210 5 9

 /\/\
/    \

finding the mathematical relationship between discrete permutations (as a whole number) requires graphing multiple decimal numbers in attempt to find an approximate numeric relationship between the numbers (e.g., the below was done by hand)

~~(128.625*9*1.074) // 1243
~~(128.625*9*1.144) // 1324

which can be described as fuzzy-logic graphing. In an array format the graphs can be finely tuned to adjust both

128.625

and

1.074

through and beyond

1.144

in parallel, or, for example, using several generator functions which maps the approximations closest to the criteria needed to get the precise multiple of 9 to get the nth permutation. With input "abcd" the procedure can be done by hand, with input of "abcdefghi" or >9 elements or digits (see 9erilous 9ermutations codegolf.stackexchange.com/q/175693)

This pattern always holds, even when you start using more that 10 numbers, though the length of the sequence is 𝑛!−1 for 𝑛 numbers. Note that to use numbers above 0 to 9, we don't change to a different base, we just multiply the number by 10𝑥, e.g. [1,12,11]10=1∗102+12∗101+11∗100=231.

of input (the value is ignored) the array format is much simpler, to keep track of, or graph the trial and error.

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, most of the work has already been done. Alternatively, Intl.NumberFormat can be extended or adjusted to return numbers in an array instead of strings; 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}) => 
      // ideally conversion to String then back to Number should not be necessary in JavaScript ("cost" of calculating .length of a String)
      ({[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?

The use of Math.trunc and remainder operator are getters, if the code portion of this proposal is reached, beyond standardization of the naming of getting certain portions of integers and arrays, developers should be able to use the same or similar methods to get and set the value of any digit of the integer or decimal, not only get the value.

Conversion of integer or decimal to array and array to integer or decimal allows developers to get and set any index or element of the array, which then can be converted back to a number comprising all of its parts - without conversion to String during the procedure.

# Michael Theriot (5 years ago)

So this would help with precision?

# guest271314 (5 years ago)

So this would help with precision?

To an appreciable degree, yes, within 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

const i = 1234.567

Each digit has a formal name which developers can get and set, whether in an array, object or number format.

Developers expect

i % 1 // .567

not

i % 1 // 0.5670000000000073

Where the initial number of digits following decimal, if any, is calculated, 0.5670000000000073 should not ever be output, as the code stops when 3 digits are calculated.

Represented as an array

[1,2,3,4,0.5,6,7]

any digit can be set, then converted back to a number.

arr[4] = arr[4] + .2 // [1,2,3,4,0.7,6,7]

Taking the procedure a step further, if arr[4] result is greater than 1 the calculation can be "carried" to then next digit in the fraction or integer part, which can then be converted back to a number with the "assurance" that the values in the array will be the precise values in the resulting number.

# Isiah Meadows (5 years ago)

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.

# guest271314 (5 years ago)

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.

# Jeremy Martin (5 years ago)

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.

# Naveen Chawla (5 years ago)

If only some of my proposals that were actually useful got this much attention

# guest271314 (5 years ago)

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.

numberToArray(0.1) // should output [.1], not [0, 1] unless that is the output you decide to output from the function

As for adding fractions, to overcome JavaScript floating point issues, the digits (or indexes of an array) can be divided by and processed in groups of three ("ones", "tens", "hundreds"). That is possible using strings, or digits, once the finite number of integer or decimal places of the input is determined.

See How do I add 1 to a big integer represented as a string in JavaScript? stackoverflow.com/questions/43614407/how-do-i-add-1-to-a-big-integer-represented-as-a-string-in-javascript. An individual could use BigInteger.js for example as used at the accepted answer could be used, or, (long form addition, subtraction, other mathematics)

You can create an array from the string in .lengths of 3 beginning from the end of the string.

Use a pattern which checks if adding 1 would result in the index of the array as a number would sum to 1000, if true, increment previous array index by 1 and fill the current array index with "000".

The pattern below only checks and adjusts last two elements of array; the same pattern can be extended to check each index of array, to properly adjust one or more of the indexes to "000" and increment the previous index by 1.

let message1 = "12345612345678901234567890";
let message2 = "12345612345678901234567999";
let message3 = "12345612345678901234999999";

function addNumberToString(str, numToAdd, digits = []) {

  const [N, len, max] = [3, str.length, 1000];

  for (let i = -N, l = len; digits.length < len / N; i -= N, l -= N) {
    digits.unshift(str.slice(i, l));
  }

  function add(m) {
    if (+digits[digits.length - m] + numToAdd < max) {
      let n = +digits[digits.length - m];
      digits[digits.length - m] = String(Number(n + numToAdd));
    } else {
        const M = m + 1;
        if (+digits[digits.length - M] + numToAdd < max) {
          let n = +digits[digits.length - M];
          digits[digits.length - M] = String(Number(n + numToAdd));
          digits[digits.length - (M - 1)] = "0".repeat(N);
        } else {
          if (digits[digits.length - (m + 1)]) {
          digits[digits.length - (M - 1)] = "0".repeat(N);
          add(m + 1);
        }
    }
  }
  return digits.join("")
}
return add(1);

}

console.log(
  addNumberToString(message1, 1)   
, addNumberToString(message2, 1)
,  addNumberToString(message3, 1)
);

which can be substituted for an array of integers instead of using strings, if the requirement was to add, subtract, or perform some other mathematical operation with the input number. Though that is the developers' prerogative what they do with the number formatted as an array in integers and a single decimal, if any.

The point of the proposal is that determining the integer, decimal if any, portions of a number and spreading those values to an array

Math.E (2.718281828459) <=> [2, 0.7, 1, 8, 2, 8, 1, 8, 2, 8, 4, 5, 9] <=> 2.718281828459 // example 3

(with optional corresponding property name, "ones", "tens", "hundreds", etc., for each of 3 groups of values, or other naming conventions, for example, in a key, value pair in a Map) from perspective here, is simpler to perform tasks with than a built-in literal number that does not have any corresponding name for each digit in the value accessible by method or getter or setter.

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 a simple form of structured output. An object of key, value pairs (similar to Intl.NumberFormat.prototype.formatToParts, with JavaScript numbers instead of strings) can also be utilized for each of the digits of integer and decimal (fraction), if any.

# J Decker (5 years ago)

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 ] }

# Jeremy Martin (5 years ago)

The proposal seeks to standardize the naming conventions of number to array and array to number, including decimals.

You're describing the hammer. When we ask for the motivation for your proposal, we're trying to understand what you want to do with the hammer, and that needs to be something more generalized than programmatically recreating an interesting number sequence (and more explicitly stated than whatever we are to infer from your test cases).

In our repeated attempts to suss that out, this seems to be your clearest description:

It is simpler to have the ability to add, subtract, divide, or otherwise

manipulate individual nth indexes of an integer or decimal represented as an array of integers potentially containing one decimal than trying to perform the same mathematical operations on a number in JavaScript (essentially broken in JavaScript due to the floating-point number issues).

That's the premise that I'm challenging. Why is it simpler, and how does it, in any appreciable way, improve upon whatever you're asserting is "broken"? As specified by your proposal, your input and output parameters are Floats, which means that the precision limitations of floating point numbers remain unaddressed.

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.

With respect, your test cases confuse the issue more than they clarify. Questions on how you'd use this structure aside (which are still important), your test cases don't actually produce a structure in which digits are accessible by nth index (e.g., the 0-grouping behavior).

# guest271314 (5 years ago)

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.

Which code are you using? Posted proof of concept, which had at least two bugs, and the answer to the question posted at Stack Overflow which fixed the bugs.

The input and output that you posted

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

is not consistent with the code posted at the answer stackoverflow.com/a/54433285 by Shidersz stackoverflow.com/users/10366495/shidersz, which is also included

at the OP

var n = numberToArray(100.00015); // [1, 0, 0, 0.0001, 5] (expected output)
arrayToNumber(n) // 100.00015 (expected output)
# guest271314 (5 years ago)

That's the premise that I'm challenging. Why is it simpler, and how does it, in any appreciable way, improve upon whatever you're asserting is "broken"?

The same way that Intl.NumberFormat.prototype.formatToParts does. Though takes the concept one step further by spreading each digit to an array - as a JavaScript number not as a JavaScript String. If the number has a decimal, the decimal portion is set at a single element of an array. If the decimal begins with a 0, continue until the first non-zero number is reached, include that number in the decimal portion within the array, and the remainder of the decimal portion is spread to remainder of array elements

Example:

var n = numberToArray(100.00015); // [1, 0, 0, 0.0001, 5]
arrayToNumber(n); // 100.00015

The proposal improves what is broken by not returning broken results relevant to decimal numbers. The proposal allows users to get and set any portion of a number using indexes of an array, which can then be converted back to a number.

If you are failing to interpret that as useful, that is your own issue. You might as well state that Intl.NumberFormat.prototype.formatToParts does not have any use. And further, JavaScript number implementation is fine just the way that it is currently implemented, unless *you *decide that any proposal is useful.

The array format is a simple data structure. Can be converted to JSON; can be extended to include a description of each digit that is a user gets or sets; e.g.,

n[0].description // {digit: 1, place: 'hundreds', decimalSibling: true,...etc.}

With respect, your test cases confuse the issue more than they clarify. Questions on how you'd use this structure aside (which are still important), your test cases don't actually produce a structure in which digits are accessible by nth index (e.g., the 0-grouping behavior).

FYI "respect" is irrelevant to the proposal. Do not need or care about what you consider "respect". You cannot offend this user.

Not sure what you mean? What are you confused about relevant to the test cases? The code at the OP includes 1) the original proof of concept; 2) code by Stack Overflow user Shidersz stackoverflow.com/users/10366495/shidersz which fixed two bugs in

the original code. Yes, the code at the OP does produce the expected result.

You are misconstruing the proposal. The code already returns the expected result. Do not ask for approval for anything. Just do and let the aftermath settle to its own level.

The proposal is asking you people who claim to be specification authors to name each element of the resulting array, for consistency, again, the example

var n = numberToArray(100.00015); // [1, 0, 0, 0.0001, 5]

as an array users obviously do not have additional data about the values in the array. What do you call the 0 at index 1? What do you call the 5 at index 4?

Before incorporating the output into an object, similar to Intl.NumberFormat.prototype.formatToParts - and including the original array in the object, or Map - am asking for standardization of the names of each digit in a spread number in an array.

Number to array, array to number is just the first part of the procedure. The part relevant to actually naming the parts, for disambiguation, is what propose here. If you are not interested, that is fine. Do not necessarily need you to do anything. Will do for self as have and continue to do independently, and name the discrete portions of the number arbitrarily, without your input.

Again, if you do not gather that this proposal is similar to and extends the functionality of Intl.NumberFormat.prototype.formatToParts, perhaps you should try to use that feature, note that "integer" and "fraction" and "minusSign" are possible return values at output, then lobby for the feature Intl.NumberFormat.prototype.formatToParts to be removed from tc39/Ecma specification, for the same reasons that you are citing at this proposal, which would then make your statement

That's the premise that I'm challenging.

consistent. Otherwise, you have only proffered standard western academic conjecture, which can be set aside where an individual is not beholden to or reliant on western academic conjecture to proceed with anything they decide to do.

# Augusto Moura (5 years ago)

The proposal improves what is broken by not returning broken results relevant to decimal numbers. The proposal allows users to get and set any portion of a number using indexes of an array, which can then be converted back to a number.

This is not a problem at all, that's not a single time I needed to do anything like that in any code I worked with, neither most of the developers here, and I dare to assume that even you used such algorithm only a few times in your career. That a lot more complex problems that need our attention, don't providing any real world examples (aside from "solving this simple algorithm problem") will get you anywhere

If you are failing to interpret that as useful, that is your own issue. You might as well state that Intl.NumberFormat.prototype.formatToParts does not have any use. And further, JavaScript number implementation is fine just the way that it is currently implemented, unless you decide that any proposal is useful.

The proposal is asking you people who claim to be specification authors to name each element of the resulting array, for consistency, again, the example

Number to array, array to number is just the first part of the procedure. The part relevant to actually naming the parts, for disambiguation, is what propose here. If you are not interested, that is fine. Do not necessarily need you to do anything. Will do for self as have and continue to do independently, and name the discrete portions of the number arbitrarily, without your input.

I don't think you understood the motivation of this mailing list and the TC39 committee, the discussions usually are for additions for the ECMAScript language (usually native APIs, syntax and implementation details), concept naming and conventions are NOT responsibility of this community. I suggest the reading of the TC39 proposal document 1 and some proposals as examples 2

At this point I'm just arguing with you for the sake of clarity to new members that reach this thread

Em ter, 12 de mar de 2019 às 13:54, guest271314 <guest271314 at gmail.com> escreveu:

That's the premise that I'm challenging. Why is it simpler, and how does it, in any appreciable way, improve upon whatever you're asserting is "broken"?

The same way that Intl.NumberFormat.prototype.formatToParts does. Though takes the concept one step further by spreading each digit to an array. If the number has a decimal, the decimal portion is set at a single element of an array. If the decimal begins with a 0, continue until the first non-zero number is reached, include that number in the decimal portion within the array, and the remainder of the decimal portion is spread to remainder of array elements

Example:

var n = numberToArray(100.00015); // [1, 0, 0, 0.0001, 5]
arrayToNumber(n); // 100.00015

The proposal improves what is broken by not returning broken results relevant to decimal numbers. The proposal allows users to get and set any portion of a number using indexes of an array, which can then be converted back to a number.

If you are failing to interpret that as useful, that is your own issue. You might as well state that Intl.NumberFormat.prototype.formatToParts does not have any use. And further, JavaScript number implementation is fine just the way that it is currently implemented, unless you decide that any proposal is useful.

The array format is a simple data structure. Can be converted to JSON; can be extended to include a description of each digit that is a user gets or sets; e.g.,

n[0].description // {digit: 1, place: 'hundreds', decimalSibling: true, ...etc.}

With respect, your test cases confuse the issue more than they clarify. Questions on how you'd use this structure aside (which are still important), your test cases don't actually produce a structure in which digits are accessible by nth index (e.g., the 0-grouping behavior).

Not sure what you mean? What are you confused about relevant to the test cases? The code at the OP includes 1) the original proof of concept; 2) code by Stack Overflow user Shidersz which fixed two bugs in the original code. Yes, the code at the OP does produce the expected result.

You are misconstruing the proposal. The code already returns the expected result. Do not ask for approval for anything. Just do and let the aftermath settle to its own level.

The proposal is asking you people who claim to be specification authors to name each element of the resulting array, for consistency, again, the example

var n = numberToArray(100.00015); // [1, 0, 0, 0.0001, 5]

as an array users obviously do not have additional data about the values in the array. What do you call the 0 at index 1? What do you call the 5 at index 4?

Before incorporating the output into an object, similar to Intl.NumberFormat.prototype.formatToParts - and including the original array in the object, or Map - am asking for standardization of the names of each digit in a spread number in an array.

Number to array, array to number is just the first part of the procedure. The part relevant to actually naming the parts, for disambiguation, is what propose here. If you are not interested, that is fine. Do not necessarily need you to do anything. Will do for self as have and continue to do independently, and name the discrete portions of the number arbitrarily, without your input.

Again, if you do not gather that this proposal is similar to and extends the functionality of Intl.NumberFormat.prototype.formatToParts, perhaps you should try to use that feature, note that "integer" and "fraction" and "minusSign" are possible return values at output, then lobby for the feature to be removed from Ecma specification, for the same reasons that you are citing at this proposal, which would then make your

premise that I'm challenging

consistent. Otherwise, you have only offered standard western academic conjecture, which can be set aside where an individual is not beholden to or reliant on western academic conjecture to proceed with anything they decide to.

With respect,

"respect" is irrelevant to the proposal. Do not need or care about what you consider "respect". You cannot offend this user.

On Tue, Mar 12, 2019 at 3:46 PM Jeremy Martin <jmar777 at gmail.com> wrote:

The proposal seeks to standardize the naming conventions of number to array and array to number, including decimals.

You're describing the hammer. When we ask for the motivation for your proposal, we're trying to understand what you want to do with the hammer, and that needs to be something more generalized than programmatically recreating an interesting number sequence (and more explicitly stated than whatever we are to infer from your test cases).

In our repeated attempts to suss that out, this seems to be your clearest description:

It is simpler to have the ability to add, subtract, divide, or otherwise manipulate individual nth indexes of an integer or decimal represented as an array of integers potentially containing one decimal than trying to perform the same mathematical operations on a number in JavaScript (essentially broken in JavaScript due to the floating-point number issues).

That's the premise that I'm challenging. Why is it simpler, and how does it, in any appreciable way, improve upon whatever you're asserting is "broken"? As specified by your proposal, your input and output parameters are Floats, which means that the precision limitations of floating point numbers remain unaddressed.

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.

With respect, your test cases confuse the issue more than they clarify. Questions on how you'd use this structure aside (which are still important), your test cases don't actually produce a structure in which digits are accessible by nth index (e.g., the 0-grouping behavior).

On Tue, Mar 12, 2019 at 2:13 AM 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.

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 nth 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, mail.mozilla.org/listinfo/es-discuss


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

-- Jeremy Martin 661.312.3853 @jmar777 / @j

-- Jeremy Martin 661.312.3853 @jmar777 / @j


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

-- Atenciosamente,

Augusto Borges de Moura

# Jeremy Martin (5 years ago)

The same way that Intl.NumberFormat.prototype.formatToParts does.

Intl.NumberFormat is used for localized string formatting. Even the numeric parts that formatToParts() returns are still represented as strings, and are not expressly intended as inputs for downstream mathematical operations. Inasmuch as it does not fix, improve upon, or otherwise specifically relate to mathematical operations (especially with respect to floating point considerations), I cannot see how this proposal does, either.

Though takes the concept one step further by spreading each digit to an

array. If the number has a decimal, the decimal portion is set at a single element of an array. If the decimal begins with a 0, continue until the first non-zero number is reached, include that number in the decimal portion within the array, and the remainder of the decimal portion is spread to remainder of array elements

That is very specific behavior that, as we still don't understand your motivation, we cannot even begin to appreciate. Why is that functionality something that you or developers in general might want? Why, for example, would we only care about direct access to the digit in the hundredths place when it's not a part of this very specific sequence?

The proposal improves what is broken by not returning broken results

relevant to decimal numbers.

It does not. This is exactly why I attempted to address some potential confusion around Floats before.

var n = numberToArray(0.3) // [0, 0.3]
arrayToNumber(n); // 0.3

That resulting 0.3 is "broken" in the exact same sense as it was when it was fed into the transformation.

The proposal allows users to get and set any portion of a number using

indexes of an array, which can then be converted back to a number.

It does not. It allows getting and setting portions of numbers at an index in an array so long as that position doesn't belong to an (arbitrarily?) specified sequence of one or more zeros and a trailing non-zero digit.

You might as well state that Intl.NumberFormat.prototype.formatToParts does

not have any use.

Of course it has use. Just not as framed or cited within the context of this proposal.

The proposal is asking you people who claim to be specification authors to

name each element of the resulting array, for consistency, again, the example.

Inasmuch as we don't understand the reasoning behind how your proposal partitions the input value, providing a coherent name for those parts is a non-starter. Again, why does your proposal treat some zeros different from non-zero digits in the same position, or different from previous or subsequent zeros encountered within the number?

I mean, this proposal is as DOA as any I've ever encountered on here, but that question is haunting me!

Otherwise, you have only offered standard western academic conjecture,

which can be set aside where an individual is not beholden to or reliant on western academic conjecture to proceed with anything they decide to.

As evidenced by my persistence in this thread, I don't count myself among them, but a significant share of the best minds in JavaScript are on this mailing list, and it seems that not a single person can make sense of this proposal. As we are on the topic of math, I would urge you to consider the common denominator, and it isn't "western academic conjecture"(??!).

And with that, I think I had better let this rest.

# guest271314 (5 years ago)

This is not a problem at all, that's not a single time I needed to do anything like that in any code I worked with, neither most of the developers here, and I dare to assume that even you used such algorithm only a few times in your career. That a lot more complex problems that need our attention, don't providing any real world examples (aside from "solving this simple algorithm problem") will get you anywhere

Given an input number, get the _n_th integer or decimal. Neither Number nor Math provides a means to do that. This proposal does provide a template for a means to do that.

# guest271314 (5 years ago)

Inasmuch as we don't understand the reasoning behind how your proposal partitions the input value, providing a coherent name for those parts is a non-starter. Again, why does your proposal treat some zeros different from non-zero digits in the same position, or different from previous or subsequent zeros encountered within the number?

Who is "we"? Are you speaking for viewers of this proposal other than yourself?

The proposal is just that, a proposal. The concept is the spread input integer or decimal to an array. In the original proof of concept, if the decimal portion contains zeros followed by a digit that is not a zero, that portion of the decimal up to and including the first non-zero digit is included in the decimal portion of the array. If there are digits following the first number that is not a zero in the decimal portion of the array, those digits are spread to the adjacent elements of the array. Why: That is the approach used to spread the number to an array, and to handle those leading zeros following decimal point.

Use cases:

  • Get any portion of a number or decimal as a discrete portion of the number
  • Manipulate discrete portion of a number using array data structure, then covert back to number
  • Ability to avoid using multiple Number, Math or remainder operator procedures to get discrete portions of a number
  • Graphing, statistics, fuzzy logic operations using number representation as an array
# guest271314 (5 years ago)

FWIW Valuable venue and feedback.