denton

Пользователь

Регистрация: 31.10.2017

Сообщения: 21956

Рейтинг: 7034

Нарушения: 105

denton

Регистрация: 31.10.2017

Сообщения: 21956

Рейтинг: 7034

Нарушения: 105

img

Допустим нам надо число number, и надо узнать, сколько в нём десятичных разрядов (например в числе '5' будет 1 разряд, в числе '3005' будет 4 разряда и т.д.). Для этого мы используем следующую строку:

Цитата:

var KappaPride = Math.log(number) * Math.LOG10E + 1 | 0;

Нажмите, чтобы раскрыть...

Для числа 1221 в задании она даёт мне 4, что верно. Хотя результатом операции Math.log(number) * Math.LOG10E будет далеко не 4, а 3.1 примерно.

Как последняя операция высрала мне 4-ку? Простите за выражение. Не понимаю в силу своей тупости, сори.

legless

Пользователь

Регистрация: 17.10.2015

Сообщения: 2074

Рейтинг: 1520

legless

Регистрация: 17.10.2015

Сообщения: 2074

Рейтинг: 1520

panicPlayer

Пользователь

Регистрация: 15.07.2019

Сообщения: 538

Рейтинг: -25

Нарушения: 110

panicPlayer

Регистрация: 15.07.2019

Сообщения: 538

Рейтинг: -25

Нарушения: 110

так я не понял, тебе нужно посчитать кол-ство символов в числе? или все таки логорифм?

denton

Пользователь

Регистрация: 31.10.2017

Сообщения: 21956

Рейтинг: 7034

Нарушения: 105

denton

Регистрация: 31.10.2017

Сообщения: 21956

Рейтинг: 7034

Нарушения: 105

img
panicPlayer сказал(а):

так я не понял, тебе нужно посчитать кол-ство символов в числе? или все таки логорифм?

Нажмите, чтобы раскрыть...

Та строка, которую я написал, считает кол-во символов в числе. Мне было непонятно, что в ней делает 0|1. Оказалось, что это побитовое или, каким-то образом округляющее любое число до меньшего по модулю значения. 

panicPlayer

Пользователь

Регистрация: 15.07.2019

Сообщения: 538

Рейтинг: -25

Нарушения: 110

panicPlayer

Регистрация: 15.07.2019

Сообщения: 538

Рейтинг: -25

Нарушения: 110

denton сказал(а):

Та строка, которую я написал, считает кол-во символов в числе. Мне было непонятно, что в ней делает 0|1. Оказалось, что это побитовое или, каким-то образом округляющее любое число до меньшего по модулю значения. 

Нажмите, чтобы раскрыть...

А перевести int в string и разбить по char и потом вернуть кол-во?)

это же js, там даже переводить не нужно))

по типу 

 

a = 1232

b = a

arr[] arr =  func toChars(b)

foreach(x : arr).

 

denton

Пользователь

Регистрация: 31.10.2017

Сообщения: 21956

Рейтинг: 7034

Нарушения: 105

denton

Регистрация: 31.10.2017

Сообщения: 21956

Рейтинг: 7034

Нарушения: 105

img
panicPlayer сказал(а):

А перевести int в string и разбить по char и потом вернуть кол-во?)

это же js, там даже переводить не нужно))

по типу 

 

a = 1232

b = a

arr[] arr =  func toChars(b)

foreach(x : arr).

 

Нажмите, чтобы раскрыть...

Зачем мне в строку переводить?

Это для определения палиндрома (число которое наоборот пишется точно так же: 55 2772 и пр.) было нужно. Для этого можно и без перевода в строку использовать деление по модулю. 

Ramdesu

Пользователь

Регистрация: 05.07.2018

Сообщения: 718

Рейтинг: 402

Ramdesu

Регистрация: 05.07.2018

Сообщения: 718

Рейтинг: 402

const number = 1221;

console.log(Math.trunc(number).toString().length); // 4

 

Так не проще сделать, чем городить какие-то сложные выражения с логарифмами и побитовыми операторами? 

 

Или так для IE и других бразуеров, не поддерживающих trunc:

 

console.log(number.toString().split('.')[0].length); // 4

 

denton сказал(а):

Это для определения палиндрома (число которое наоборот пишется точно так же: 55 2772 и пр.) было нужно

Нажмите, чтобы раскрыть...

+number.toString().split('').reverse().join('') === number

Dont Mind

Пользователь

Регистрация: 25.05.2015

Сообщения: 4614

Рейтинг: 3335

Dont Mind

Регистрация: 25.05.2015

Сообщения: 4614

Рейтинг: 3335

Ramdesu сказал(а):

console.log(number.toString().split('.')[0].length); // 4

Нажмите, чтобы раскрыть...

 

итого ты порождаешь на ровном месте 3 строки в памяти. Это наиболее медленный из всех способов. Логарифм один из самых быстрых и практически не зависит от размера переданного числа.

denton сказал(а):

Допустим нам надо число number, и надо узнать, сколько в нём десятичных разрядов (например в числе '5' будет 1 разряд, в числе '3005' будет 4 разряда и т.д.). Для этого мы используем следующую строку:

Для числа 1221 в задании она даёт мне 4, что верно. Хотя результатом операции Math.log(number) * Math.LOG10E будет далеко не 4, а 3.1 примерно.

Как последняя операция высрала мне 4-ку? Простите за выражение. Не понимаю в силу своей тупости, сори.

Нажмите, чтобы раскрыть...

 

я так понимаю 1|0 отвечает за направление округление к большему целому числу. Честно, я думаю будет читабельнее использовать явное округление результата к большему целому (https://javascript.ru/Math.ceil)

denton

Пользователь

Регистрация: 31.10.2017

Сообщения: 21956

Рейтинг: 7034

Нарушения: 105

denton

Регистрация: 31.10.2017

Сообщения: 21956

Рейтинг: 7034

Нарушения: 105

img
Dont Mind сказал(а):

 

итого ты порождаешь на ровном месте 3 строки в памяти. Это наиболее медленный из всех способов. Логарифм один из самых быстрых и практически не зависит от размера переданного числа.

 

 

я так понимаю 1|0 отвечает за направление округление к большему целому числу. Честно, я думаю будет читабельнее использовать явное округление результата к большему целому (https://javascript.ru/Math.ceil)

Нажмите, чтобы раскрыть...

 

Как узнать, насколько тяжеловесны дефолтные методы для памяти?

У твоего метода есть нюанс, он вроде бы отрицательные числа приводит к большему, но не по модулю числу, что иногда бывает важно.

 

Dont Mind

Пользователь

Регистрация: 25.05.2015

Сообщения: 4614

Рейтинг: 3335

Dont Mind

Регистрация: 25.05.2015

Сообщения: 4614

Рейтинг: 3335

denton сказал(а):

 

Как узнать, насколько тяжеловесны дефолтные методы для памяти?

У твоего метода есть нюанс, он вроде бы отрицательные числа приводит к большему, но не по модулю числу, что иногда бывает важно.

 

Нажмите, чтобы раскрыть...

 

Есть два пункта.

1) Понимать, сколько места память выделяет под тот или иной элемент и изменяем ли он в памяти. Например строка в большинстве языков програмирование - неизменяемый объект, и любая модификация строки порождает новую строку.

2) Сложность выполнения. Сколько нужно сделать операцию чтобы реализовать алгоритм.

Комбинация этих двух пунктов и определяет лучший алгоритм для решения задачи. Например, для задачи поиска разрадности числа есть 4 алгоритма - сравнение, логарифм, деление и приведение к строке и подсчет длины.  Самым быстрым является первый, но он хуже всего читается. Логарифм имеет постоянное время выполнения (он всегда сводится к преобразованием математическим и сложению "бесконечного" ряда), деление линейно зависит от N, преобразование к строке посимвольно превращает каждый элемент сначала с char символ, порождает строку и дальше считает её длину. Т.е. тоже N, но еще и память засирает.

 

Не берусь конкретно говорить про JS, но хранение числа типа int занимает 8 байт места, на примере питона пустая строка занимает 40 байт в памяти + байт для каждого символа. На маленьких масштабах это не критично, но по сути в 5 раз больше места. НЕ стоит гнаться за этим всегда, ибо читаемость временами важнее экономии байтов, но я сталкивался с задачами на питоне, где правильный алгоритм спасал от ошибки заканчивания оперативной памяти и на порядок сокращал время выполнения функции.

Ramdesu

Пользователь

Регистрация: 05.07.2018

Сообщения: 718

Рейтинг: 402

Ramdesu

Регистрация: 05.07.2018

Сообщения: 718

Рейтинг: 402

Dont Mind сказал(а):

я так понимаю 1|0 отвечает за направление округление к большему целому числу. Честно, я думаю будет читабельнее использовать явное округление результата к большему целому (https://javascript.ru/Math.ceil)

Нажмите, чтобы раскрыть...

|0 отбрасывает дробную часть числа. В ЖС, вроде, только trunc и |0 может сделать это. При этом |0 ведет себя неправильно с большими числами (если не ошибаюсь, с ним можно юзать только числа от −2 147 483 648 до 2 147 483 647). split я привел как одну из вариаций полифила для IE. В нормальном браузере никто не мешает юзать trunc. Насчет скорости: в статье, ссылку на которую скинули во 2 посте, написаны два самых быстрых метода (и это, само собой, не сплит), можно юзать их. Но там статья 2013 года. Думаю, если потестить, то trunc будет на уровне с ними.

Dont Mind

Пользователь

Регистрация: 25.05.2015

Сообщения: 4614

Рейтинг: 3335

Dont Mind

Регистрация: 25.05.2015

Сообщения: 4614

Рейтинг: 3335

Ramdesu сказал(а):

|0 отбрасывает дробную часть числа. В ЖС, вроде, только trunc и |0 может сделать это. При этом |0 ведет себя неправильно с большими числами (если не ошибаюсь, с ним можно юзать только числа от −2 147 483 648 до 2 147 483 647). split я привел как одна из вариаций полифила для IE. В нормальном браузере никто не мешает юзать trunc. Насчет скорости, в статье, ссылку на которую скинули во 2 статье, написаны два самых быстрых метода (и это, само собой, не сплит), можно юзать их. Но там статья 2013 года. Думаю, если потестить, то trunc будет на уровне с ними.

Нажмите, чтобы раскрыть...

 

алгоритма поика разрадности числа в принципе являются языко-независимыми. И скорость их выполнения зависит в большей степени от сложности алгоритма, а не языка. Наибольшую скорость имеет метод сравнения, насколько я знаю, ибо там меньше всего операций, но он лимитирован местами. Логарифм же имеет неизменную сложность (из-за использования преобразования Фурье под капотом) вне зависимости от размера N.

Я просто не JS-ер, признаю, просто вариант со строкой в принципе самый медленный и ресурсоемкий и не стоит его рекомендовать использовать.

Я так понимаю |0 работает в рамках int?

ScienceT

Пользователь

Регистрация: 17.05.2019

Сообщения: 146

Рейтинг: 36

ScienceT

Регистрация: 17.05.2019

Сообщения: 146

Рейтинг: 36

|0 – отбрасывает дробную часть числа (в данном случае). То что у вас получилось ~3.1 в ходе выполнения – правильно. Но вы забыли про '+ 1', в результате вычисления этой операции и получается ~4.1хххххх, после чего идёт отбрасывание дробной части и в ответе получаем 4.

Dont Mind

Пользователь

Регистрация: 25.05.2015

Сообщения: 4614

Рейтинг: 3335

Dont Mind

Регистрация: 25.05.2015

Сообщения: 4614

Рейтинг: 3335

ScienceT сказал(а):

Но вы забыли про '+ 1'

Нажмите, чтобы раскрыть...

 

боже, я чет тупил и думал что это именно конструкция такая +1|0 xD