需求:
将输入的整数或小数转换为数组,并将可能包含小数的整数数组转换为数字。
限制:
在过程中不要使用字符串方法或将输入或输出转换为字符串(在编写代码的每个版本中都遵循自我限制)。
上下文和用例
BigInt
在一些浏览器中可用,但没有 BigDecimal
。 使用JavaScript编程语言应该可以将整数或小数转换为数组,以及将数组转换为整数或小数。在过程中,输入和输出不需要转换为字符串。
可以通过调整数组中第 n 位置的小数或整数来调整整数或小数的第 n 位数字,例如,直接尝试解决OEIS A217626问题。
~~(128.625*9*1.074)//1243
~~(128.625*9*1.144)//1324
可以通过引用数组的索引来操纵小数部分,然后将数组转换回数字。
当前规范正在进行中,涉及输入的小数部分处理时可能会存在一些挑战,特别是当有前导零时更为复杂。
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]
我尝试将整数或小数分散到一个数组中。将数字或整数转换为数组的函数必须能够转换为生成器函数,以实现此功能。
[...Math.E] -> [2, 0.7, 1, 8, 2, 8, 1, 8, 2, 8, 4, 5, 9] -> 2.718281828459
通过将函数设置为Number.prototype[Symbol.iterator]
的值来实现功能,该函数名为numberToArray
。
最新版本的代码(其中某些概念和代码的原始版本基于使用JavaScript获取数字的小数部分; 不使用toString和parseInt方法将int值转换为String; 将整数转换为数字数组的问题和答案),这个版本有两个错误,即arrayToNumber
的测试用例输出结果中100.05010000000497
应为100.00015
,-83.082
应为-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});
问题:
- 如何修复现有代码中列出的错误?
- 在不使用字符串方法或在过程中转换输入或输出为字符串的限制下,是否可以改进或以完全不同的方式组合代码以满足要求?
- 当前规范是否可以改进,以使使用的术语更加清晰,并避免对小数的预期输出产生混淆?
123.001
被表示为[[1,2,3],[0,0,1]]
,我可能误解了重点,但可以将其扩展到123.001
->[[1],[1,2,3],[0,0,1]]
和-123.001
->[[0],[1,2,3],[0,0,1]]
,其中[[修饰符],[整数],[小数]]
。 - Bibberty