C++ 非常大数的对数

C++ 非常大数的对数,c++,logging,logarithm,arbitrary-precision,C++,Logging,Logarithm,Arbitrary Precision,我得找一份数量很大的日志 我用C语言做这个++ 我已经做了一个乘法,加法,减法,除法的函数,但是对数有问题。我不需要代码,我需要一个简单的想法如何使用这些函数 谢谢 附言。 对不起,我忘了告诉你:我必须只找到那个数字的二元对数 第2页 我发现: int floorLog2(无符号int n){ 如果(n==0) 返回-1; int pos=0; 如果(n>=(1=16;pos+=16;} 如果(n>=(1>=8;pos+=8;} 如果(n>=(1>=4;pos+=4;} 如果(n>=(1>=2;

我得找一份数量很大的日志

我用C语言做这个++

我已经做了一个乘法,加法,减法,除法的函数,但是对数有问题。我不需要代码,我需要一个简单的想法如何使用这些函数

谢谢

附言。 对不起,我忘了告诉你:我必须只找到那个数字的二元对数

第2页 我发现:

int floorLog2(无符号int n){
如果(n==0)
返回-1;
int pos=0;
如果(n>=(1=16;pos+=16;}
如果(n>=(1>=8;pos+=8;}
如果(n>=(1>=4;pos+=4;}
如果(n>=(1>=2;pos+=2;}

如果(n>=(1我假设你想知道如何“手工”计算对数,那么我告诉你我发现了什么

请看一看,其中描述了如何手动对数。您可以将其作为一个算法来实现。这是“Euler是如何实现的”一篇文章。我也发现很有希望


我想有更复杂的方法可以做到这一点,但它们太复杂了,你可能不想实现它们。

我假设你正在编写一个自己的bignum类。如果你只关心log2的整数结果,那就很容易了。取不为零的最高有效位的日志,然后为每个字节添加8这是假设每个字节都有0-255的值。这些值仅在±0.5范围内精确,但速度非常快

[0][42][53] (10805 in bytes)
    log2(42) = 5
    + 8*1    = 8    (because of the one byte lower than MSB)
             = 13  (Actual: 13.39941145)
如果您的值以10位为基数,则等于
log2(MSB)+3.32192809*num\u digits\u小于\u MSB

[0][5][7][6][2] (5762)
 log2(5)        =  2.321928095
 + 3.32192809*3 =  9.96578427  (because 3 digits lower than MSB)
                =  12.28771  (Actual: 12.49235395)
(only accurate for numbers with less than ~10 million digits)
如果你使用你在维基百科上找到的算法,它会非常慢。(但如果你需要小数,它是准确的)

有人指出,当MSB很小时(仍在±.5范围内,但不在更远的范围内),我的方法是不准确的,但这很容易解决,只需将最上面的两个字节换成一个数字,记下该数字的日志,然后对小于该数字的字节进行乘法。我相信这将精确到0.5%,并且仍然比正常对数快得多

[1][42][53] (76341 in bytes)
    log2(1*256+42) = ?
    log2(298) = 8.21916852046
    + 8*1     = 8    (because of the one byte lower than MSB)
              = 16.21916852046  (Actual: 16.2201704643)

对于基数为10的数字,它是
log2([mostSignificantDigit]*10+[secondmostSignificantDigit])+3.32192809*[remainingDigitCount]


如果性能仍然存在问题,您可以使用log2的查找表,而不是使用完整的对数函数。

为什么不调用log函数?这是家庭作业吗?从10000000000000000000000000000调用log函数?!这可能吗?绝对可能。将1e300毫无困难地传递到log。嗯……谢谢,但我认为这是个问题tic因为我的长数字存储在字符数组中…我如何以1e300形式传入函数?不要将数字存储为文本。将它们转换为数字。在这种情况下,您希望转换为
双精度
。请不要告诉我您为
字符*
编写了加法和乘法例程!谢谢,但我认为使用这些方法会花费太长时间,因为我有一个问题,就是一个二元对数。我能这样做吗?:@KamilHismatullin:你能这样做吗?是的。会很慢吗?哦,是的。谢谢。请看一看:。谢谢你看我的问题。我相信你给出的答案值得留下来,可能会有所帮助其他人正在寻找.NET透视图。再次感谢。@RaheelKhan:其他答案已经有了更快的速度,并且使用了相同的算法。他们已经提供了很好的.NET实现,不需要我的错误在他们旁边:对于以10为基数的数字,这不精确到小数点。有解决方法吗?对于以10为基数的数字,这是
log2([mostSignificantDigit]*10+[SecondMostSignificantDigit])+3.32192809*[remainingDigitCount]
。您还可以使用*100并使用三位数字计算日志,以进一步提高准确性。唯一的技巧是您必须确保有足够的数字,但这很简单。
[1][42][53] (76341 in bytes)
    log2(1*256+42) = ?
    log2(298) = 8.21916852046
    + 8*1     = 8    (because of the one byte lower than MSB)
              = 16.21916852046  (Actual: 16.2201704643)