Requirement:
Convert input integer or decimal to an array and convert array of integers which may include a decimal to a number.
Restriction:
Do not use string methods or convert input or output to a string during the procedure (a self-imposed restriction followed throughout each version of the code composed).
Context and use cases
BigInt
in 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 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.
The current specification is WIP and could be considered challenging to describe relevant to the processing of the decimal portion of input, specifically where there are leading zeros.
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]
Essentially, am attempting to spread an integer or decimal to an array. The function which converts a number or integer to an array must be capable of being converted to a generator function, for the ability to achieve
[...Math.E] -> [2, 0.7, 1, 8, 2, 8, 1, 8, 2, 8, 4, 5, 9] -> 2.718281828459
by setting the function as value of Number.prototype[Symbol.iterator]
to numberToArray
.
The most recent version of the code (some of the concepts and original versions of the code were based on questions and answers at Get decimal portion of a number with JavaScript; Converting int value to String without using toString and parseInt method; Convert integer to array of digits), which has two bugs at resulting output of tests cases from arrayToNumber
100.05010000000497
should be 100.00015
and -83.082
should be -83.782
.
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});
Questions:
- How to fix the listed bugs in the existing code?
- Within the restriction of not using string methods or converting input or output to a string during the procedure, can the code be improved or composed in a different manner altogether to meet the requirement?
- Can the current specification be improved as to clarity of terms used and to avoid confusion as to what the expected output is for decimals?