[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Как посчитать корень произвольной степени?
motorway
Как посчитать корень произвольной степени из числа произвольной длины с помощью BC Math? Функция bcpow не работает с дробными корнями. Библиотеку GMP не очень хочется устанавливать.



Спустя 13 часов, 27 минут, 40 секунд (24.10.2009 - 13:19) Sylex написал(а):
motorway
вообще-то это сложная задача... для очень больших чисел smile.gif

Спустя 57 минут, 56 секунд (24.10.2009 - 14:17) motorway написал(а):
Думаю, в XXI веке ее должны были научиться реализовывать. Если есть функция bcpow, то должны были сделать что-то для извлечения корня.

Спустя 2 часа, 20 минут, 29 секунд (24.10.2009 - 16:38) Sylex написал(а):
motorway
скажу так:

если бы был способ найден для больших чисел, то большинство алгоритмов шифрования стали бы обратимыми - т.е. отсутствовала бы необходимость делать перебор - можно было просто "получить" код обратным ходом

для более менее приемлимых чисел - конечно, есть что-то

Спустя 14 минут, 16 секунд (24.10.2009 - 16:52) motorway написал(а):
Вы акцентируете внимание не на том: у меня был вопрос не во времени (а именно оно является главным препятствием для взлома шифров), а в наличии такой функции.
Пока что мне нужна такая стандартная функция для извлечения корня из чисел произвольной длины. То, что она будет медленной, второстепенный вопрос. Есть же функции перемножения типа bcmul. То, что они будут долго работать для очень больших чисел - второй вопрос

Спустя 2 минуты, 34 секунды (24.10.2009 - 16:55) motorway написал(а):
Пока можно считать, что меня интересуют числа порядка 1000 знаков

Спустя 19 минут, 49 секунд (24.10.2009 - 17:14) Joker написал(а):
Цитата (motorway @ 24.10.2009 - 19:55)
Пока можно считать, что меня интересуют числа порядка 1000 знаков

Если найдете прямой способ получения корня из числа с 1000 разрядов, а не перебором, то вам наверника вручат какую нибудь премию и вы вайдете в историю.


Спустя 3 минуты, 18 секунд (24.10.2009 - 17:18) motorway написал(а):
В общем, мне нужна тогда хотя бы наилучшая функция на текущий момент

Спустя 24 минуты, 21 секунда (24.10.2009 - 17:42) Michael написал(а):
Из школьной математики:
Корень n-ой степени из x означает x в степени 1/n.
Алгоритм:
(пример - корень 10-й степени из 9785625)
PHP
$x 5;  // - число
$n 10// - степень
echo 'Имеем  - ',$x,'<br>';
$y pow($x$n);  // получили 9785625
echo 'Возведенное число - ',$y,'<br>';

// вот теперь корень считаем от 9785625
$z pow($y1/$n);
echo 
'Взят корень - ',$z'<br>';


P.S. Joker, торчит мне премию rolleyes.gif

Спустя 8 минут, 11 секунд (24.10.2009 - 17:50) motorway написал(а):
Пока что здесь был пример с небольшими числами. Это действительно можно сделать так. Но если будет так:
$y=bcsub(bcpow(32,32),1);
И берем корень 32-й степени
То результат извлечения пишет 32, а должно быть 31.......

Спустя 13 минут, 19 секунд (24.10.2009 - 18:04) Sylex написал(а):
motorway
почему должно быть 31?

Michael
введи в свою функцию число из 1000 знаков

хотя это еще не много)

Спустя 5 минут, 38 секунд (24.10.2009 - 18:09) motorway написал(а):
Потому что это число меньше 32^32 на единицу. Следовательно, корень будет меньше 32. Если вынести за скобки, будет так:

sqrt32(32^32-1)=sqrt32(32^32*(1-1/32^32))=32*sqrt32(1-1/32^32)=32*k, где k<1.

sqrt32 - корень 32-й степени

Спустя 17 минут, 25 секунд (24.10.2009 - 18:27) Sylex написал(а):
motorway
ты явно что-то путаешь....

p.s. но математику я уже забыл, дальше спорить не буду laugh.gif

Спустя 6 минут, 50 секунд (24.10.2009 - 18:33) motorway написал(а):
С какой стати путаю? Это также элементарно, как то, что корень из 81 - 9, а из 80 - уже 8,....

Спустя 15 минут, 38 секунд (24.10.2009 - 18:49) Michael написал(а):
Да bcpow не работает с действительными числами в степени.

Но работает с ними - pow. !!!

Число $x=1.0E+300 - хранится в типе double. Из него взять нужный корень - как выше я указал (используя pow).
Осталось в цикле исходное "большое" число $z делить на $x с помощью bcdiv
и выводить из под корня до того как остаток от $z станет меньше $x - тогда и его
выведем pow.

Спустя 9 минут, 10 секунд (24.10.2009 - 18:58) Michael написал(а):
Цитата (Sylex @ 24.10.2009 - 15:04)
Michael
введи в свою функцию число из 1000 знаков

хотя это еще не много)

Из 1000 не введу - тип не позволит.
Но корень 200 из 1.0E+300
считает моментом
А 10^1000 = 10^300 * 10^300 * 10^300 * 10^100
Т.е. четыре раза прогнать и все.

Спустя 3 минуты, 6 секунд (24.10.2009 - 19:01) motorway написал(а):
Не очень понял. Может, вы это проделаете для примера на числе 32^32-1, взяв из него корень 32 степени? wink.gif Должно получиться 31,.....
Мне нужно как раз без ограничений по всяким типам
И для 10^500

Спустя 6 минут, 9 секунд (24.10.2009 - 19:07) Michael написал(а):
31 == корень32(32^32) - 1

Что имеете ввиду? Зачем отнимать единицу?




Спустя 2 минуты, 57 секунд (24.10.2009 - 19:10) motorway написал(а):
Чтобы проверить, работает или нет. Если вы берете корень 32-й степени из 32^32 и получается 32, то для числа (32^32)-1 должно получиться 31,.....

В общем, из вот этого числа возьмите корень 32-й степени: 1461501637330902918203684832716283019655932542975

А затем из такого корень 100-й степени:

43464682451352972707813381341537484216938733500433929256253245511177292366930286758936298421200416808294313409875433761374279812918424447586649029125705236124331757751823459921392609873154029194012375560611112197131518750641724872215130094395969777682316106137600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Спустя 4 минуты, 17 секунд (24.10.2009 - 19:15) Michael написал(а):
Цитата (motorway @ 24.10.2009 - 16:10)
Чтобы проверить, работает или нет. Если вы берете корень 32-й степени из 32^32 и получается 32, то для числа (32^32)-1 должно получиться 31,.....

С чего бы это?
Числа
(32^32)
(32^32) -1
равны с милимилимили... погрешностью
И корень из этого числа будет 32
или 31.9999999999999999999999999999999999999999999999999999999999

Спустя 1 минута, 1 секунда (24.10.2009 - 19:16) motorway написал(а):
Мне как раз важна эта погрешность. Они НЕ равны с абсолютной точностью.

Спустя 6 минут, 26 секунд (24.10.2009 - 19:22) Michael написал(а):
Ну тогда округляй до меньшего целого (floor). Но вас я не понимаю -
при чем тогда здесь математика, если вы просто что-то хотите.

Спустя 2 минуты, 47 секунд (24.10.2009 - 19:25) motorway написал(а):
Я хочу иметь работающую математическую функцию. Для начала я хотел проверить ваш пример. Но для моего случая 32^32-1 он не дал правильного ответа. Поэтому мне нужна нормальная функция

Спустя 11 часов, 9 минут, 23 секунды (25.10.2009 - 07:34) Sylex написал(а):
как и предполагал... все вызвано точностью чисел с плавающей точкой smile.gif проснулись biggrin.gif

Спустя 8 часов, 38 минут, 17 секунд (25.10.2009 - 16:13) Michael написал(а):
Цитата (motorway @ 24.10.2009 - 16:25)
Я хочу иметь работающую математическую функцию. Для начала я хотел проверить ваш пример. Но для моего случая 32^32-1 он не дал правильного ответа. Поэтому мне нужна нормальная функция

Это не будет математическая функция, это будет функция реализующая, то что вам надо
По моему алгоритму
корень32(32^32 - 1)
вернет 31.9999999999999999999999 - чистая математика

Ваша функция будет содержать

floor(корень32(32^32 - 1))
и вернет 31 - то что вам требовалось.

И вообще для чего все это - вычислять из больших чисел произвольные корни? Для интереса? smile.gif




Спустя 51 минута, 46 секунд (25.10.2009 - 17:04) motorway написал(а):
Я имел в виду функцию на PHP.
Если ваша функция действительно вернет 31.999, то хотелось бы иметь ее полный код.
Функция нужна для использования в составе математической программы, работающей с большими числами.

Спустя 18 минут, 12 секунд (25.10.2009 - 17:23) Michael написал(а):
Цитата (motorway @ 25.10.2009 - 14:04)
Я имел в виду функцию на PHP.
Если ваша функция действительно вернет 31.999, то хотелось бы иметь ее полный код.
Функция нужна для использования в составе математической программы, работающей с большими числами.

Здесь сначала пишут свой код, а потом спрашивают что не так.
Алгоритм кстати простой и описан мной в топиках от 14:42 и 15:49.

В кратце напомню смысл - "большое" число в цикле раскладывается на "маленькие"
(10E+300), которые выводятся из под корня с помощью функции pow, которая от
10E+300 возьмет любой дробный корень.

Спустя 1 минута, 25 секунд (25.10.2009 - 17:24) Michael написал(а):
Цитата (motorway @ 24.10.2009 - 15:33)
С какой стати путаю? Это также элементарно, как то, что корень из 81 - 9, а из 80 - уже 8,....

Жесть cool.gif

Спустя 3 часа, 27 минут, 27 секунд (25.10.2009 - 20:51) motorway написал(а):
Вы не согласны? wink.gif

Спустя 12 часов, 35 минут, 18 секунд (26.10.2009 - 09:27) Sylex написал(а):
laugh.gif

Спустя 47 минут, 51 секунда (26.10.2009 - 10:15) glock18 написал(а):
Капец, какая тут тема...

Следует отметить, что Michael математически абсолютно прав, ссылаясь симметричность операций возведения в степень и взятия корня.

motorway, то о чем говорите вы, с математической точки зрения полнейшая ересь.

И как правильно сказал Sylex для float/double математическая точность "отдыхает". Не говоря уже о том, что 1000 знаков непредставимы этими типами. Могу посоветовать:

1. взять какой-нибудь язык, не накладывающий ограничений на размер числа. lisp например позволяет складывать числа типа 999999999999999999999999999999. может и с возведение в степень получится чего.

2. написать свой тип для пхп. че-нить типа hugedouble и работать с ним. Написать такой можно, что он удовлетворял конкретно вашим потребностям. встроенной функции нет, как и числового типа, которым можно было бы представить такое число.

Спустя 12 часов, 10 минут, 51 секунда (26.10.2009 - 22:25) motorway написал(а):
Цитата
motorway, то о чем говорите вы, с математической точки зрения полнейшая ересь.

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

Я с самого начала сказал, что мне не подходят функции, где будут какие-то ограничения по размеру числа.

Большие числа представляются в виде строк, и с ними спокойно можно работать с помощью BC Math, если вам это не известно

Спустя 25 минут, 38 секунд (26.10.2009 - 22:51) glock18 написал(а):
motorway
у меня складывается ощущение, что вы неадекватны. по крайней мере, ваши доводы говорят мне об этом.

Спустя 24 минуты, 13 секунд (26.10.2009 - 23:15) motorway написал(а):
Вы тоже ничего конкретного не пишете. Если ошибка есть, так укажите. А то несколько пользователей начали загадочно ставить смайлики, как будто что-то не так. Почему вы не хотите указать на эту конкретную "ересь"?

Спустя 1 минута, 29 секунд (26.10.2009 - 23:17) Joker написал(а):
glock18
motorway
Не сортесь, мир вам братья smile.gif


Спустя 2 минуты, 29 секунд (26.10.2009 - 23:19) motorway написал(а):
Да нет, мне просто интересно выяснить истину. Ссориться не имею обыкновения, лишь интересует, что вызвало такие возражения. У меня было все правильно
Как я понял, вызвало сомнения, что корень из 80 будет иметь целую часть 8. Так проверьте!

Спустя 4 минуты, 12 секунд (26.10.2009 - 23:23) Joker написал(а):
Он эксперт ты нет поэтому лучше полизать пятки и если ты прав в конце концов эксперт признает это если действовать логично и последовательно, а слушать как эксперт говорит что он не прав это блаженство)))

Спустя 4 минуты, 30 секунд (26.10.2009 - 23:28) motorway написал(а):
Если вы о статусе на этом форуме, это ни о чем не говорит. Есть истина, и ей все равно. Мне важна истина. Если у меня была "ересь" только из-за того, что я не эксперт, то тогда обсуждение не имеет смысла. Если кто-то из присутствующих ученых может указать на мою ошибку с точки зрения науки, буду рад выслушать! laugh.gif
А главное, я не понимаю смысл писать, что у вас ересь, если не указывать конкретное место и в чем она состоит.

Спустя 14 минут, 10 секунд (26.10.2009 - 23:42) glock18 написал(а):
Joker ты не в тему. и ты сделал не те выводы, которые следовало.

motorway да, я как раз говорил о том, что математически sqrt(n^2 - 1) равно n - 1 лишь при n = 1. Остальное, что касается "целой части", прежде не поднималось. Задача рассматривалась только с точки зрения программирования (приведение float -> int возвращает целую часть). математически оно неверно, если отдельно не оговорить.

вот и все. а насчет сверхбольших чисел - да, можно любое число представить в виде строки. только и реализация математических операций будет сильно отличаться от стандартной. если BCMath умеет брать корень любой степени, то им и стоит воспользоваться.

из своего прошлого могу сказать, что один раз у меня была задача реализовать тип с плавающей точкой на целых числах и самые простые операции на ассемблере. так вот даже с ними возникло куча проблем, и уж ни о каких 309 значных числах и говорить там не приходилось.

на основе этого могу сказать лишь, что пляски со строками "как с числами" достаточно сложное дело. а произвольный корень вовсе не умножение. если готовой функции нет, то могу предложить только "умеренно разумный" перебор - навскидку определять количество цифр результата и перебирать с определенным шагом, зависящим от отклонения от результата. Так называемый эвристический перебор.

Спустя 7 минут, 56 секунд (26.10.2009 - 23:50) motorway написал(а):
Цитата
motorway да, я как раз говорил о том, что математически sqrt(n^2 - 1) равно n - 1 лишь при n = 1.

Значит, вы просто неправильно интерпретировали мой пост. Если вы посмотрите на мой начальный пост, то там будет:

Цитата
С какой стати путаю? Это также элементарно, как то, что корень из 81 - 9, а из 80 - уже 8,....


Я не говорил, что корень из 80 - 8. Там ясно видна запятая и точки - то есть, после нее что-то идет. Странно, что этого не заметили и другие. Ну ладно.
Цитата
если BCMath умеет брать корень любой степени, то им и стоит воспользоваться.


Вопрос как раз в этом и состоял. Насколько мне известно, он не умеет брать любой корень. И нужно было выяснить, как его взять. Вот и все.

Спустя 5 минут, 43 секунды (26.10.2009 - 23:56) glock18 написал(а):
Мм, да запятую не разглядел smile.gif Она там не так чтобы ясна smile.gif
Цитата
Вопрос как раз в этом и состоял. Насколько мне известно, он не умеет брать любой корень. И нужно было выяснить, как его взять. Вот и все.


ну, если не найдете, можете воспользоваться эвристическим поиском. он творит чудеса smile.gif

Спустя 3 минуты, 58 секунд (27.10.2009 - 00:00) Joker написал(а):
Цитата (glock18 @ 27.10.2009 - 02:42)
Joker ты не в тему. и ты сделал не те выводы, которые следовало.


Выводы из чего?)

Цитата (motorway @ 27.10.2009 - 02:28)
Если вы о статусе на этом форуме, это ни о чем не говорит.


Это тебе не говорит, а многим тут многое говорит... попробуй пробейся поймешь что к чему.

А по теме:

Цитата (motorway @ 24.10.2009 - 02:52)
Как посчитать корень произвольной степени из числа произвольной длины


впринципе не возможно, будет ограничение по используемой памяти сервера, ограничения всегда есть и всегда будут, пусть ограничение хоть в терабайт хоть в сто бай, можно всегда придумать число которое заполнит всю память и еще и нехватит.

Поэтому стоит сначало задаться вопросом какое ограничение нужно... а после уже искать способ решения и он всегда есть но надо искать и не писать тут как это можно сделать... на данный момент я не видел от автора каких либо действий по поиску и предоставления результатов для совета. Хотя могу ошибаться может быть просмотрел тема уже не маленькая.

Спустя 13 часов, 29 минут, 24 секунды (27.10.2009 - 13:29) motorway написал(а):
Насчет статуса форума - кто-то, может, просто недавно сюда попал, а на самом деле он человек с высшим образованием и даже кандидат наук, или готовиться им стать.
Цитата
впринципе не возможно, будет ограничение по используемой памяти сервера, ограничения всегда есть и всегда будут, пусть ограничение хоть в терабайт хоть в сто бай, можно всегда придумать число которое заполнит всю память и еще и нехватит.

Я имел в виду, конечно, не абсолютно произвольные числа, а достаточно большие, т.е. такие, как в BC Math. По крайней мере чтобы не было явных ограничений типа как в integer, double, etc. В том же мануале PHP про BC Math написано: arbitrary precision numbers - то есть произвольной точности, но разумеется, не совершенно огромной длины.
На несколько тысяч знаков памяти, думаю, должно хватить. Пока что можно считать, что бОльшие числа не нужны.
Я уже пробовал выяснять в других местах, есть ли такая готовая функция, но что-то не очень эффективно. В основном советы в русле данной темы.
Но я считаю, что должна быть уже отработанная и проверенная функция, которой пользуются многие, дабы не изобретать велосипед каждый раз.

Спустя 1 час, 34 минуты, 34 секунды (27.10.2009 - 15:04) Michael написал(а):
Цитата
Там ясно видна запятая и точки - то есть, после нее что-то идет

Написали так и никто не понял, в программировании запятая разряды вроде нигде не разделяет.
Жаль, что мной предложенный алгоритм так и не был вами обдуман.
Ну ладно, за настойчивость, держи smile.gif , ( и получай свою пятерку )
PHP
function koren($numb$koren)
{
    
// $numb - строка bc  с числом,  $koren - значение корня
            
$ost doubleval($numb);
            if (
$ost != INF) return pow($ost1/$koren);    
            
$ch pow(10,300);
            
$bch bcpow('10','300');
            
$mnoz pow($ch1/$koren); // выведенный из под корня множитель
            
$rez 1;            
            
$vih false;
            while (! 
$vih)
            {
                
$ostbc bcdiv($numb$bch100);
                
$rez *= $mnoz;
                
$ost doubleval($ostbc);
                if (
$ost != INF
                {
                    
$rez *= pow($ost1/$koren);
                    
$vih true;
                }
                else 
$numb $ostbc;
                
            }
    return 
$rez;        
}
////////
// Пример работы
$x bcpow('733','424'); // 733 в степени 424
echo 'В числе - ' strlen($x) . ' цифр<br>'// выведет кол-во  цифр в числе - 1215
echo koren($x424); // возьмем из $x корень 424 степени
// выведет - 733


Корень 100-ой степени от твоего числа
4346468245135297270781338134153.......
тоже считает - 40400.

Спустя 7 часов, 46 минут, 30 секунд (27.10.2009 - 22:50) motorway написал(а):
Спасибо, буду разбираться и тестировать. Кроме этого, постараюсь найти еще варианты функций.

Спустя 3 месяца, 9 дней, 19 часов, 30 минут, 52 секунды (9.02.2010 - 18:21) Гость_Герман написал(а):
я школер и фиг знаю как быстро посчитать 2/3^4 a?)

Спустя 38 секунд (9.02.2010 - 18:22) Гость_Герман написал(а):
скажите умные люди=)

Спустя 3 минуты, 21 секунда (9.02.2010 - 18:25) Guest написал(а):
и например 4^9 как можно посчитать быстрей степень, или только так: 4*4*4*4.....

Спустя 12 минут, 19 секунд (9.02.2010 - 18:37) Michael написал(а):
Калькулятором воспользоваться не пробовал?
Например тем который в "Пуск->Программы->Стандартные->Калькулятор"

Спустя 10 минут, 53 секунды (9.02.2010 - 18:48) Гость_Герман написал(а):
эт понятно, если без....
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.