【发布时间】:2019-01-30 03:36:48
【问题描述】:
要求:
将输入的整数或小数转换为数组,并将可能包含小数的整数数组转换为数字。
限制:
在此过程中不要使用字符串方法或将输入或输出转换为字符串(在编写的每个版本的代码中都遵循自我强加的限制)。
上下文和用例
BigInt 在某些浏览器中可用,但不是BigDecimal。使用 JavaScript 编程语言应该可以实现从整数或小数到数组和数组到整数或小数的转换。在此过程中,输入和输出不需要转换为字符串。
能够通过调整数组的nth索引处的小数或整数来调整整数或小数的nth位,以尝试直接解决OEIS A217626,例如
~~(128.625*9*1.074)//1243
~~(128.625*9*1.144)//1324
可以通过引用数组的索引来操作小数部分,然后将数组转换回数字。
当前的规范是 WIP,描述与处理输入的小数部分相关的内容可能被认为具有挑战性,特别是在有前导零的情况下。
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。
代码的最新版本(代码的一些概念和原始版本基于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 的问题和答案),在测试结果输出中有两个错误来自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]]其中[[Modifier],[Int],[Decimal]]
标签: javascript arrays ecmascript-6 integer decimal