Автор Тема: pow() и bcpow() не катят  (Прочитано 5603 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Orme

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 15
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pow() и bcpow() не катят
« : 25 Января 2007, 19:15:53 »
Нужна функция или алгоритм, возводящие число в степень.

Возвращаемое значение и передаваемые аргументы могут быть очень большими,
поэтому pow() не подходит.
bcpow() тоже не подходит, потому что в качестве аргументов принимает
только натуральные числа, а нужно, чтобы принимала любые положительные,
в том числе и дробные, и меньше 1.
//
строка большое_число mypow ( строка большое_число, строка степень_любое_полож_число )

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

-----
Да, gmp_pow() воспользоваться не могу, потому что работаю под win32.
    И может с ней аналогичная ситуация.

Оффлайн andymc

  • Фанат форума
  • Старожил
  • ****
  • Сообщений: 400
  • +1/-0
  • 0
    • Просмотр профиля
pow() и bcpow() не катят
« Ответ #1 : 26 Января 2007, 13:33:09 »
Orme
Объясни, почему pow() не подходит?
Большое число - насколько большое: 1000, миллион, миллиард?

Оффлайн CGVictor

  • теперь местный
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 2511
  • +0/-0
  • 2
    • Просмотр профиля
    • http://cg.net.ru
pow() и bcpow() не катят
« Ответ #2 : 26 Января 2007, 13:42:20 »
[off]andymc
Максимальный вывод у pow - 2^31.[/off]
LJ: Backslashed life (rss)

Оффлайн andymc

  • Фанат форума
  • Старожил
  • ****
  • Сообщений: 400
  • +1/-0
  • 0
    • Просмотр профиля
pow() и bcpow() не катят
« Ответ #3 : 27 Января 2007, 11:16:19 »
CGVictor, Orme
[OFF]Эксперимент показал, что максимальная степень по базе \'2\' - это 39 (pow(2,39))
pow(2,39) = 549 755 813 888
pow(2,40) = 1.099 511 627 78E+012
Дальше идёт округление
Функци bcpow() действительно не считает дробные степени.[/OFF]

Пусть m - степень (дробная). например, 25,86
Тогда m1 = floor(m); // целая часть 25
m2 = m - m1; // дробная часть 0,86
Теперь, согласно форумуле
bcpow(a, m) = bcpow(a, m1) * pow(a, m2);

Готовая функция может выглядеть так:
function mypow($x$y$scale 0){
	
if (
is_float($y)){
	
	
$y1 floor($y);
	
	
$y2 $y $y1;
	
	
return 
bcmul(bcpow($x$y1), pow($x$y2), $scale);
	
} else {
	
	
return 
bcpow($x$y);
	
}
}

Оффлайн Orme

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 15
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pow() и bcpow() не катят
« Ответ #4 : 28 Января 2007, 00:55:00 »
andymc
Цитировать
bcpow(a, m) = bcpow(a, m1) * pow(a, m2)


Откуда формула?

Оффлайн Orme

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 15
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pow() и bcpow() не катят
« Ответ #5 : 28 Января 2007, 01:00:36 »
andymc
Цитировать
function mypow($x, $y, $scale = 0){
    if (is_float($y)){
        $y1 = floor($y);
        $y2 = $y - $y1;
        return bcmul(bcpow($x, $y1), pow($x, $y2), $scale);
    } else {
        return bcpow($x, $y);
    }
}


Не будет работать. Нужна формула (ln(a) * a^X)*x + a^X.
В ней тоже много проблем, которые стандартными способами не решишь.

Оффлайн andymc

  • Фанат форума
  • Старожил
  • ****
  • Сообщений: 400
  • +1/-0
  • 0
    • Просмотр профиля
pow() и bcpow() не катят
« Ответ #6 : 28 Января 2007, 01:24:16 »
Я сам проверял, работает нормально
Цитировать
bcpow(a, m) = bcpow(a, m1) * pow(a, m2)
это формула школьного курса, переделанная под php (\'a\' в степени \'c\'+\'b\' = \'a\' в степени \'c\' умножить на \'a\' в степени \'b\')
Логически елси подумать, это должно работать

Оффлайн Orme

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 15
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pow() и bcpow() не катят
« Ответ #7 : 30 Января 2007, 22:06:21 »
m2 - все равно дробь. Смысл какой?

Нужно привести в итоге к целочисленным вычислениям.

Тут надо переводить decimal в fraction (типа 1/2, 5/4)

Далее по формуле a^m/n = n-ный корень из a^m

Оффлайн andymc

  • Фанат форума
  • Старожил
  • ****
  • Сообщений: 400
  • +1/-0
  • 0
    • Просмотр профиля
pow() и bcpow() не катят
« Ответ #8 : 30 Января 2007, 22:42:36 »
m2 - дробь, но pow() же работает с дробями. Смысл в том, чтобы разделить задачу на 2 части: отдельно считать целое и дробное.
Цитировать
переводить decimal в fraction (типа 1/2, 5/4)
что-то мне кажется, что это невозможно
Цитировать
a^m/n = n-ный корень из a^m
я сначала тоже так думал, только вот n-ный корень ты не сможешь точно подсчитать:
pow() ограничена
bcpow() не работает с дробями

ты функцию проверял? Она работает?

Оффлайн Orme

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 15
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pow() и bcpow() не катят
« Ответ #9 : 01 Февраля 2007, 08:24:11 »
Цитировать
что-то мне кажется, что это невозможно


- очень даже несложная функция:


function dec2frac($decimal) {

	
$decimal = (string)$decimal;
	
$num "";
	
$den "1";
	
$dec false;
	

	
for (
$i 0$len strlen($decimal); $i $len$i++) {
	
	
if (
$dec$den gmp_mul($den"10");
	
	
if (
$decimal{$i} == ".") {
	
	
	
$dec true;
	
	
}else{
	
	
	
$num .= $decimal{$i};
	
	
}
	
}
	

	
if(
$den == "1") return $num;
	

	
if (
strpos($num"0") === 0$num ltrim($num"0");
	

	
$gcd gmp_gcd($num$den);
	

	
$num gmp_strval(gmp_div($num$gcd));
	
$den gmp_strval(gmp_div($den$gcd));
	

	
return 
$num."/".$den;

}

Оффлайн Orme

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 15
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pow() и bcpow() не катят
« Ответ #10 : 01 Февраля 2007, 08:25:42 »
Да, только здесь gmp используется. Забыл сказать.
Но, в принципе, можно и без нее обойтись.

Оффлайн andymc

  • Фанат форума
  • Старожил
  • ****
  • Сообщений: 400
  • +1/-0
  • 0
    • Просмотр профиля
pow() и bcpow() не катят
« Ответ #11 : 01 Февраля 2007, 13:36:58 »
спасибо, что расказал про GMP.

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28