Forum Webscript.Ru
Программирование => PHP => Тема начата: Orme от 25 Января 2007, 19:15:53
-
Нужна функция или алгоритм, возводящие число в степень.
Возвращаемое значение и передаваемые аргументы могут быть очень большими,
поэтому pow() не подходит.
bcpow() тоже не подходит, потому что в качестве аргументов принимает
только натуральные числа, а нужно, чтобы принимала любые положительные,
в том числе и дробные, и меньше 1.
//
строка большое_число mypow ( строка большое_число, строка степень_любое_полож_число )
Может, кто-нибудь сталкивался с аналогичной проблемой, и может помочь?
-----
Да, gmp_pow() воспользоваться не могу, потому что работаю под win32.
И может с ней аналогичная ситуация.
-
Orme
Объясни, почему pow() не подходит?
Большое число - насколько большое: 1000, миллион, миллиард?
-
[off]andymc
Максимальный вывод у pow - 2^31.[/off]
-
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);
}
}
-
andymc
bcpow(a, m) = bcpow(a, m1) * pow(a, m2)
Откуда формула?
-
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.
В ней тоже много проблем, которые стандартными способами не решишь.
-
Я сам проверял, работает нормально
bcpow(a, m) = bcpow(a, m1) * pow(a, m2)
это формула школьного курса, переделанная под php (\'a\' в степени \'c\'+\'b\' = \'a\' в степени \'c\' умножить на \'a\' в степени \'b\')
Логически елси подумать, это должно работать
-
m2 - все равно дробь. Смысл какой?
Нужно привести в итоге к целочисленным вычислениям.
Тут надо переводить decimal в fraction (типа 1/2, 5/4)
Далее по формуле a^m/n = n-ный корень из a^m
-
m2 - дробь, но pow() же работает с дробями. Смысл в том, чтобы разделить задачу на 2 части: отдельно считать целое и дробное.
переводить decimal в fraction (типа 1/2, 5/4)
что-то мне кажется, что это невозможно a^m/n = n-ный корень из a^m
я сначала тоже так думал, только вот n-ный корень ты не сможешь точно подсчитать:
pow() ограничена
bcpow() не работает с дробями
ты функцию проверял? Она работает?
-
что-то мне кажется, что это невозможно
- очень даже несложная функция:
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;
}
-
Да, только здесь gmp используется. Забыл сказать.
Но, в принципе, можно и без нее обойтись.
-
спасибо, что расказал про GMP.