如何获得一个非常大的数字(PHP)的log()?

时间:2014-06-16 02:06:08

标签: php

我查看了php-big numbersBC MathGMP来处理php中非常大的数字。但似乎没有一个函数与php的log()等效。例如,我想这样做:

$result = log($bigNumber, 2);

有人知道在php中获取任意精度点数的日志库2的另一种方法吗?也许我错过了一个函数,库或公式。

编辑:php-bignumbers似乎只有一个基数为10的函数log10()

4 个答案:

答案 0 :(得分:3)

一般情况下,如果你想实现高精度日志自己的计算,我建议首先使用对数的基本特征:

log_a(x) = log_b(x) / log_b(a) |=> thus you can recalulate logarith to any base
log(x*y) = log(x) + log(y)
log(a**n) = n*log(a)

其中log_a(x) - 表示x的基数a的对数; log表示自然对数

所以log(1000000000000000000000.123) = 21*log(1.000000000000000000000123)

和高精度的log(1 + x) 使用引用的算法 http://en.wikipedia.org/wiki/Natural_logarithm#High_precision

答案 1 :(得分:1)

结合目前建议的一个解决方案是使用这个公式:

log2($num) = log10($num) / log10(2)

php-big numbers 一起使用,因为它具有预先制作的log10功能。

例如,在安装php-big数字库之后,请使用:

$log2 = log10($bigNum) / log10(2);

我个人决定使用不同的数学/逻辑,以便不需要日志功能,只需使用bcmath作为大数字。

答案 2 :(得分:1)

基础2的一大优点是计数和移位成为工具集的一部分。

所以一种方法来获得一个' log2'一个数字是将它转换为二进制字符串并计算位数。

您可以通过在循环中除以2来等效地完成此操作。但在我看来,计数会更有效率。

如果从右边开始计数,可以使用

gmp_scan0和gmp_scan1。但是你必须以某种方式将混合位转换为全1和0。

但是使用gmp_strval(num,2),你可以生成一个字符串并在其上做一个strpos。

如果要转换整个值,则可以在其上执行(strlen - 1)。

显然,只有在需要整数日志时才会有效。

答案 3 :(得分:0)

我最近有一个非常类似的问题..所以我只是为了使用内置日志找到小数部分而大大缩放了数字..(我出于某种原因优先考虑log10 ..不要#39; t问...人们很奇怪,我也是 我希望这是足够的自我解决方案.. 它返回一个浮点值(因为那是我需要的)

function gmp_log($num, $base=10, $full=true)
{
    if($base == 10)
        $string = gmp_strval($num);
    else
        $string = gmp_strval($num,$base);

    $intpart = strlen($string)-1;

    if(!$full)
        return $intpart;

    if($base ==10)
    {
        $string = substr_replace($string, ".", 1, 0);
        $number = floatval($string);
        $lg = $intpart + log10($number);
        return $lg;
    }
    else
    {
        $string = gmp_strval($num);
        $intpart = strlen($string)-1;
        $string = substr_replace($string, ".", 1, 0);
        $number = floatval($string);
        $lg = $intpart + log10($number);

        $lb = $lg / log10($base);
        return $lb;
    }
}
它很快,很脏......但是它足以获得一些RSA大小的整数日志;)

用法也是直截了当的

$N = gmp_init("11002930366353704069");
echo gmp_log($N,10)."\n";
echo gmp_log($N,10, false)."\n";
echo gmp_log($N,2)."\n";
echo gmp_log($N,16)."\n";

返回

19.041508364472 
19 
63.254521604973 
15.813630401243