Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Большие числа (https://javascript.ru/forum/misc/70752-bolshie-chisla.html)

Gtfuc 29.09.2017 22:07

Большие числа
 
Добрый день! Нужен совет по поводу работы с большими числами?
Есть следующий код в котором надо найти количество нулей выражения a, где 23! - это факториал числа 23, 24!! - это факториал числа, который выглядит следующим образом: 24!! = 2*4*6*8*10*12*14*16*18*20*22*24, для 25!! - наоборот, произведение нечетных чисел. Каким образом можно избавиться от экспоненты в степени, при этом не используя сторонних библиотек и т.д?
var a = '23!*24!!*25!*26!!*27!!';
		var arr = a.split('*');
		var res = [];
		var multi = 1;
		for (var k=0; k<arr.length; k++){
			var val = 1;
			if (arr[k].substring(arr[k].length-2) == '!!'){
				if (parseInt(arr[k])%2 == 0){
					for(var l = 2; l<=parseInt(arr[k]); l=l+2){
						val *= l;
					}
					res.push(val);
				}
				else {
					for(var h = 1; h<=parseInt(arr[k]); h=h+2){
						val *= h;
					}
					res.push(val);
				}
			}
			else {
				for (var i=2; i<=parseInt(arr[k]); i++){
					val *= i;
				}
				res.push(val);
			}
		}
		for (var g=0; g<res.length; g++){
			multi *= res[g];
		}
		var zeros = String(multi).split('');
			var count = 0;
			for (var j=zeros.length-1; j>=0; j--){
				if(zeros[j]==0){
					count++;
				}
				else if(zeros[j]!=0){
					break;
				}
			}
			console.log(zeros);
			console.log(count);

рони 29.09.2017 22:13

Gtfuc,
:lol: табуном пошли ...
https://javascript.ru/forum/misc/707...tml#post465933

Alexandroppolus 29.09.2017 22:26

из ссылки рони надо взять функцию getFactZeros

для '23!*24!!*25!*26!!*27!!' результат будет равен
getFactZeros(23) + getFactZeros(12) + getFactZeros(25) + getFactZeros(27)

и вот почему:
1) 26!!*27!! = 27! , тут все понятно
2) 24!! - ни что иное как 2^12 * 12!. Мы считаем сколько раз пятерка входит в множители. В степени двойки её нет, тут остается только 12!

на самом деле ноль дает пара сомножителей (2,5), но в любом факториале двоек больше, пятерки в дефиците, потому только их и считаем. Как следствие, можно просто складывать результаты getFactZeros, посколько во всех компонентах не будет "свободных" пятерок, и перемножение компонентов не даст дополнительных нулей.

рони 29.09.2017 22:34

Alexandroppolus,
getFactZeros - вычисляет нули в конце числа , а не во всём числе

Alexandroppolus 29.09.2017 22:39

рони,
строки 37-39 первого поста намекают, что таки надо в конце )

рони 29.09.2017 22:52

Цитата:

Сообщение от Alexandroppolus
строки 37-39 первого поста намекают, что таки надо в конце )

вы хорошо разбирате чужой код.

рони 29.09.2017 23:27

большие числа, факториал
 
Alexandroppolus,
абалдеть всё сходится :victory: :thanks:
function sum(x, y) {
    var res = "0";
    for (var i = 0; i < y; i++) res = diff(res, "" + x);
    return res
}

function diff(max, min) {
    if (+max < +min) {
        var t = max;
        max = min;
        min = t
    }
    max = max.split("").reverse();
    min = min.split("").reverse();
    var len = Math.max(max.length, min.length),
        result = [];
    for (var i = 0, b = 0, c = 0; i <= len; i++) {
        b = (+max[i] || 0) + (+min[i] || 0) + c;
        result[i] = b > 9 ? (c = 1, b - 10) : (c = 0, b)
    }
    return result.reverse().join("").replace(/^0+/, "")
}

function getFactZeros(x) {
    var z = 0;
    while (x) {
        x = x / 5 | 0;
        z += x
    }
    return z
}
var a = "23!*24!!*25!*26!!*27!!";
var arr = a.split("*");
var val = "1";
for (var k = 0; k < arr.length; k++)
    if (arr[k].substring(arr[k].length - 2) == "!!")
        if (parseInt(arr[k]) % 2 == 0)
            for (var l = 2; l <= parseInt(arr[k]); l = l + 2) val = sum(val, "" + l);
        else
            for (var h = 1; h <= parseInt(arr[k]); h = h + 2) val = sum(val, "" + h);
        else
    for (var i = 2; i <= parseInt(arr[k]); i++) val = sum(val, "" + i);
var zeros = val;
var count = 0;
for (var j = zeros.length - 1; j >= 0; j--)
    if (zeros[j] == 0) count++;
    else if (zeros[j] != 0) break;
console.log(zeros);
console.log(count);
console.log(getFactZeros(23) + getFactZeros(12) + getFactZeros(25) + getFactZeros(27));

Gtfuc 30.09.2017 01:55

рони,
спасибо за помощь. + перед переменной - это преобразование к числу таким образом происходит? Можно немного оффтопа по следующему вопросу: каким образом можно достичь вашего уровня в программировании, может у вас есть некий план развития, качественные ресурсы, книги, совет, интересует ваше мнение, дабы не потеряться в многообразии всего-всего?

Gtfuc 30.09.2017 02:08

Каким образом можно оптимизировать производительность вычисления? Если увеличить количество слагаемых в выражении?('45!*63!*28!*55!!*35!!*45!!*25 !!*65!!*50!!*40!!*95!!*25!*45!*63!*28!*55!!'). До какого максимального предела строки можно вычислять, зависит от аппаратной мощности или как?

рони 30.09.2017 09:48

Цитата:

Сообщение от Gtfuc
+ перед переменной - это преобразование к числу таким образом происходит?

да
Цитата:

Сообщение от Gtfuc
каким образом

практика(писать код для реального проекта), интерес.
Цитата:

Сообщение от Gtfuc
Каким образом можно оптимизировать производительность вычисления?

не вычислять факториалы (пример Alexandroppolus, пост №3 ) искать быстрый код
Цитата:

Сообщение от Gtfuc
До какого максимального предела строки можно вычислять, зависит от аппаратной мощности или как?

да и посмотреть документацию на длину строки/массива.


Часовой пояс GMT +3, время: 08:32.