Math 计算表示任意基中整数所需的长度

Math 计算表示任意基中整数所需的长度,math,base,logarithm,radix,Math,Base,Logarithm,Radix,我有一个整数在任意基上表示的长度。假设长度是15,底边是36。然后我想计算出这个整数在另一个任意基中的表示时间。i、 e,转换为基数2可能导致长度为68 我知道这是按照下面的思路进行的,但我不能完全理解我需要的地板和天花板,我得到的一些结果远远不够: length * log(fromBase) / log(toBase) 遵循类似Mathematica的语法,让 Log[b,n] 表示n的以b为底的对数。让Log[n]表示n的自然对数 然后是比率 Log[b1,n]/Log[b2,n]

我有一个整数在任意基上表示的长度。假设长度是15,底边是36。然后我想计算出这个整数在另一个任意基中的表示时间。i、 e,转换为基数2可能导致长度为68

我知道这是按照下面的思路进行的,但我不能完全理解我需要的地板和天花板,我得到的一些结果远远不够:

length * log(fromBase) / log(toBase)

遵循类似Mathematica的语法,让

Log[b,n]
表示n的以b为底的对数。让
Log[n]
表示
n
的自然对数

然后是比率

Log[b1,n]/Log[b2,n]
是常数,等于

Log[b2]/Log[b1]
这个比率是一个乘数,用于根据base
b2
中的位数计算base
b1
中的位数(如果您这样看,则反之亦然)。对于问题中的示例,需要一个15位的基数为36的数字

15*Log[36]/Log[2] == 77.5489
以2位数为基数。当然,这正是你在问题中所拥有的。您只需将最终答案四舍五入到下一个整数即可


当然,我不确定为什么你似乎得到了一些远未达到的结果

不幸的是,没有高精度的计算就没有精确解。例如,(我将使用MATLAB进行我的工作,包括我自己编写的用于高精度工作的工具)2^200是什么?在基数10中,我们得到:

vpij(2)^200
ans =
    1606938044258990275541962092341162602522202993782792835301376
该数字用201个2进制数字以二进制表示。但是,2^200-1只需要200个以2为基数的数字来表示

vpij(2)^200 - 1
ans =
    1606938044258990275541962092341162602522202993782792835301375
现在,我们可以计算这些数字的对数,作为双精度,只取最高阶的数字。我们需要将1添加到一个数字的基数2日志中,以了解表示该数字所需的基数2位数

format long g
1 + log2(vpij(2)^200)
ans =
   201

1 + log2(vpij(2)^200 - 1)
ans =
   201
这里log2就是这样做的,取最上面的十进制数字来计算日志。请注意,它无法判断第二个数字是否真的需要少一个数字才能以二进制形式存储

vpij2bin(vpij(2)^200)
ans =
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

vpij2bin(vpij(2)^200 - 1)
ans =
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
通过对这些数字进行高精度记录,我们可以看到发生了什么。因此,精确到小数点后100位

log2(hpf(2,100)^200)
ans =
200

log2(hpf(2,100)^200 - 1)
ans =
199.9999999999999999999999999999999999999999999999999999999999991022086719253476184905817230522465495
这两个数字之间的差别非常小

log10(hpf(2,100)^200) - log10(hpf(2,100)^200 - 1)
ans =
2.702621195974725251000559400026211938865e-61
因此,任何使用日志的计算都必须失败,除非采用高精度日志本身。充其量,你可以在一个数字内正确,但不能超过这个数字。因此,如果你的目标仅仅是为数字分配足够的空间,那么总是比显然需要的多分配一个数字。这应该是足够的,直到你开始与真正巨大的权力


(VPIJ是MATLAB中的一种新的可变精度整数形式,它将直接取代我以前的VPI工具。HPF已在文件交换中提供。)

您可以在不使用对数的情况下获得准确答案。沿着任意底面的半径向上走,直到数字正好在里面

Python示例:

def count_digits(number, base):
    radix = 1
    while number >= base ** radix:
        radix += 1
    return radix

基本上,以数字为单位的长度是log(baseN)+1,被截断为整数。@hotlick有没有不计算实际数字的log的方法?这个数字通常太大,不可能简单地做到这一点(想想以10为底的数百位数字)。我试图做的是计算缓冲区的大小,在我以后转换数字时,将数字放入缓冲区。@Alec:通过将前几个数字的对数加上数字的位数减去1,你可以很容易地大致估算出数字的对数(以10为基数)。例如,log(42598)为~4.629。或者,你可以计算log(4.26)=0.629,数字加5,减去1,得到4.629。当然,你可以做一个表格。或者您可以将数字除掉。@BobMurphy-注意,从某些数字子集计算日志通常不足以得到准确的值。因此,2^100-1需要100个以2为基数的数字。但2^100需要101个以2为基数的数字。以10为基数表示2^100,我们有1267650600228229401496703205376,这个数字足够大,以至于双精度日志无法看到差异。两个log10值之间的差值约为3.4e-31,因此使用标准日志函数将无法查看。这是一个接近但并非完美的解决方案。为了计算足够大的尺寸,这可能是可以的(但如果您需要确切的尺寸,则不可以)。