Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 25.05.2020, 01:03
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Malleys
Не будет, например, 4.3 будет считаться чётным числом
А кто-то вел речь о десятичных? Даже детишки знают, что для целых чисел деление можно заменить логическим сдвигом, четность проверять по младшему разряду, по естественным причинам. Десятичное представление иное.
Ответить с цитированием
  #12 (permalink)  
Старый 25.05.2020, 10:34
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

Сообщение от Malleys
Error, просто, интересно и правильное решение!
поясни почему интересное и правильное с твоей точки зрения
const doubleEveryEven = arr => arr.map(n => 0 === n % 2 ? n + n : n);

здесь нет лишнего умножения
Error,
приветсвую, если аватарка таже
laimas,
абсолютно правильно написал для целых чисел
Ответить с цитированием
  #13 (permalink)  
Старый 25.05.2020, 12:56
Аватар для Error
Интересующийся
Отправить личное сообщение для Error Посмотреть профиль Найти все сообщения от Error
 
Регистрация: 30.04.2020
Сообщений: 17

Vlasenko Fedor,
приветствую Вас! Да, это я. Что касается моего решения, то мне захотелось избежать применения любых условных операторов. Хотя это, конечно, не должно быть целью.

Понятие чётности вводится обычно именно для целых чисел (для рациональных нет смысла рассматривать вопросы делимости). Поэтому предлагаю считать, что все элементы массива — целые числа. Значит, любое решение, применимое к целым числам, можно считать правильным.
Ответить с цитированием
  #14 (permalink)  
Старый 25.05.2020, 15:52
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,692

Сообщение от laimas
Даже детишки знают, что для целых чисел деление можно заменить логическим сдвигом,
Поосторожнее надо быть детишкам.
console.log(2**30<<1)
Ответить с цитированием
  #15 (permalink)  
Старый 25.05.2020, 15:57
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от voraa
Поосторожнее надо быть детишкам
Но, но, это также как и с десятичными, не всегда будет гут, но с другой стороны мы же иногда и округляем, а значит допускаем. А деление, это сдвиг вправо, а не влево
Ответить с цитированием
  #16 (permalink)  
Старый 25.05.2020, 16:30
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

Сообщение от voraa
Поосторожнее надо быть детишкам.
console.log(2**30<<1)
a<<b
умножение числа a на 2 в степени b
console.log(2**30&1)
Ответить с цитированием
  #17 (permalink)  
Старый 25.05.2020, 23:47
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от 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.
Ответить с цитированием
  #18 (permalink)  
Старый 26.05.2020, 03:22
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Malleys,
и зачем это научный труд, неужели бы все отвечающие не вели посты свои в ключе необходимом, если бы условием было для всех и вся?

Сообщение от Malleys
Совершенно спокойно можно написать дробное число
Однако же не написано.
Ответить с цитированием
  #19 (permalink)  
Старый 26.05.2020, 04:24
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от laimas
и зачем это
Ты сам написал, что твои детки знают про целочисленные сдвиги, а разве они не знают про то, что с этим могут возникнуть проблемы когда будут неподходящие целые числа?

Твой метод хорош, просто нужно было уточнить, что он правильно работает только с типом BigInt, а с типом Number требуются дополнительные проверки!

Последний раз редактировалось Malleys, 26.05.2020 в 04:28.
Ответить с цитированием
  #20 (permalink)  
Старый 26.05.2020, 12:50
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Malleys
Твой метод хорош, просто нужно было уточнить
Это не мой метод, а если руководствоваться постулатом "Раз использовался Array, а не конкретный типизированный массив для целых чисел; а также тип Number, то странно предполагать, что речь идёт не о десятичных числах.", то надо смотреть ширше, ибо массив может содержать и другое. Почему тогда не добавить еще и о проверке типа перед нами, например, в стрингах он или нет, и можно ли его вообще умножать.

Все увидели в том, что представлено, только то, что увидели для этого и даны решения различные, и они все правильные. А если предполагать, что там может быть что-то, ну так все об этом уже высказались - будет, значит нужно брать подходящее.

Это же касается и о логическом сдвиге, такие операции быстрые ибо это операция над одним орперандом в аккумуляторе, она выгоднее. Но никто же и говорил, что такая операция способна на все, никто же не использует операторы/функции, которые не дают нужного результата, стоит ли об этом говорить.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выполнить скрипт только после того, как элемент с определенным id появляется в DOM strs Events/DOM/Window 10 26.05.2018 18:10
Как сделать клик по элементу только один раз в день Alexodiy Events/DOM/Window 7 19.01.2018 15:23
Как можно развернуть/свернуть только один блок по клику? nina_ jQuery 2 19.07.2016 13:07
Как сделать, чтобы при вводе числа в поле добавлялись разделители групп разрядов? Hurray Элементы интерфейса 13 18.02.2015 14:07
Как сделать чтобы text() брал только текст родителя без текста вложенных контейнеров? Andrey32 jQuery 3 23.05.2009 01:33