Сообщение от laimas
|
А кто-то вел речь о десятичных?
|
Раз использовался Array, а не конкретный типизированный массив для целых чисел; а также тип Number, то странно предполагать, что речь идёт не о десятичных числах. Совершенно спокойно можно написать дробное число и оно будет неверно обработано. Может для тебя ОК писать код, который делает неожиданные вещи и продолжает выполняться, но я предпочёл бы использовать правильный тип или выкидывать исключение при нарушении требовании (диапазон целых чисел и проверка на целочисленность)
Использование правильного типа оберегает от проблем...
function doubleEveryEven (a) {
return a.map(n => n * (2n - (n & 1n)));
}
console.log(doubleEveryEven([11n, 0n, 9n, 3n, 10n, 4n]));
В этом примере вы можете использовать целые числа и всегда получать правильное вычисление.
Если же хотите использовать тип Number и работать именно с целыми числами и использовать оператор &, то следует провести проверки.
Хотя оператор & работает с 32-битными числами, он подходит для задачи, поскольку нас интересует только последний бит.
function doubleEveryEven (a) {
return a.map(n => {
if(!Number.isSafeInteger(n))
throw new RangeError(`The provided number ${n} is not a safe integer to operate with.`);
if((n & 1) == 0) {
const doubleN = 2 * n;
if(!Number.isSafeInteger(doubleN))
throw new RangeError(`The calculated number ${doubleN} is not a safe integer to operate with.`);
return doubleN;
} else {
return n;
}
});
}
console.log(doubleEveryEven([11, 0, 9, 3, 10, 4]));
Почему удвоенное число типа Number тоже проверяется на безопасность? Поскольку безопасное число, умноженное на 2, может оказаться не безопасным...
alert(8456834563856384 * 2 === 16913669127712767);
А на самом деле так...
alert(8456834563856384n * 2n === 16913669127712767n);
Что же касается умножения при помощи побитового сдвига, то нужно учитывать, что работает с 32-битными числами от -(2 ** 31) до 2 ** 31 - 1.
function doubleEveryEven (a) {
return a.map(n => {
if(Number.isSafeInteger(n) && ((n > 2 ** 31 - 1) || (n < -(2 ** 31))))
throw new RangeError(`The provided number ${n} is not a safe 32-bit integer to operate with.`);
if((n & 1) == 0) {
if((n > 2 ** 30 - 1) || (n < -(2 ** 30)))
throw new RangeError(`A double of number has got to be a safe 32-bit integer to operate with.`);
return n << 1;
} else {
return n;
}
});
}
console.log(doubleEveryEven([11, 0, 9, 3, 10, 4]));
Сообщение от Vlasenko Fedor
|
laimas, абсолютно правильно написал для целых чисел
|
Не упомянуты проверки, соответственно не для всех целых чисел правильные результаты.
Сообщение от Vlasenko Fedor
|
поясни почему интересное и правильное с твоей точки зрения
|
Если именно для типа Number и кол-во значащих цифр не имеет значения, но тут оказалось всё хуже — пишем тип Number, думаем о BigInt.