计算存储十进制数所需的位数

28

考虑无符号整数表示。为了存储一个包含以下数字的十进制数,需要多少位:

i) 3 digits ii) 4 digits iii) 6 digits iv) n digits

我知道无符号整数的范围是0到2^n,但我不明白表示一个数字所需位数如何取决于它。


实际上,无符号整数的范围是0到2^n-1,其中n为位数。 - rghome
@rghome 这个属性有名字吗?我觉得它很棒。 - Marwan
@Marwan,我不太确定你指的是哪个属性,但也许“指数”是你要找的词。 - rghome
我正在谈论的是“无符号整数的范围是n位时0到2^n - 1”。这里需要的比特数是log_2,这只是巧合吗? - Marwan
也许我有点疯狂,算了吧。 - Marwan
13个回答

35

你只需要为每种情况计算范围,然后找到最低的大于该范围的2的幂。

例如,在 i) 中,3个十进制数字 -> 10^3 = 1000 可能的数字,因此您必须找到最低的大于1000的2的幂,这种情况下是2^10 = 1024 (10位)。

编辑: 基本上,您需要找到具有与十进制中相同数量可能性的数字位数(在此情况下为二进制)。

要根据数字位数计算可能性:possibilities=base^ndigits

因此,如果您在十进制(基数10)中有3位数字,则有10^3=1000个可能性。然后您必须找到二进制(位数,基数2)的数字位数,以使可能性至少为1000,这种情况下是2^10=1024(9位不足,因为2^9=512小于1000)。

如果您将其推广,就会得到: 2^nbits=possibilities <=> nbits=log2(possibilities)

应用于i): log2(1000)=9.97,由于位数必须是整数,因此必须将其向上取整到10。


4
取决于你所在的地区,在葡萄牙我们使用“,”作为小数分隔符。无论如何,在我的回答中我将其改为“.”。 - guardianpt
14
我认为正确的公式是 floor(log2(n)) + 1,否则例如对于1024的结果将为10,这是错误的。 维基百科链接 - ubik
1
@ubik 实际上,10位二进制数足以表示1024个数字(从0到1023)。当然,如果您想知道表示特定数字所需的位数,则该公式是正确的。 - guardianpt
@guardianpt,你是对的。请忽略我的评论,我误解了问题。 - ubik
@ubik:你的公式适用于有符号数。 - Nagendra Nigade
显示剩余3条评论

21

存储n个整数所需的二进制位数的公式(例如,0n-1)是:

loge(n) / loge(2)

并向上取整。

例如,对于值-128到127(有符号字节)或0到255(无符号字节),整数的数量为256,因此n为256,从上述公式中得到8。

对于0n,在上述公式中使用n + 1(共有n + 1个整数)。

在计算器上,loge可能只标记为logln(自然对数)。


4
谢谢您提供简单的公式,而不是冗长的解释。这样更加实用和简明扼要。 - ICW
4
如果我没错的话,_log₂(n)_ 应该可以很好地工作。 - Danii
1
如果你的计算器上有一个以2为底的对数按钮,那么答案是肯定的。 - rghome
1
@Isaac 人类需要解释,而机器不需要推理。 - Eduardo Sebastian

11

在基数为 b 的情况下,n 位数能够表示的最大数字是 bn-1。因此,在 N 个二进制位中能够表示的最大数字是 2N-1。我们需要找到满足以下条件的最小整数 N

2N-1 ≥ bn-1
⇒ 2N ≥ bn

对于上述最后一个式子两边同时取以 2 为底的对数,得到:

log2 2N ≥ log2 bn
⇒ N ≥ log2 bn
⇒ N ≥ log bn / log 2

由于我们想要找到满足上述关系的最小整数 N,因此需要求出 log bn / log 2 并向上取整即可得到 N

在上述式子中,对数的底数可以是任意值,只要两个底数相同即可。由于我们此处关心的是 b = 10 的情况,因此可以使用以 10 为底的对数,利用 log1010n == n 这个等式。

n = 3 时:

N = ⌈3 / log10 2⌉ = 10

n = 4 时:

N = ⌈4 / log10 2⌉ = 14

n = 6 时:

N = ⌈6 / log10 2⌉ = 20

通常来说,对于n个十进制位数:

N = ⌈n / log10 2⌉


这是一个很好的答案。我建议指出log(10^n) == n,这样读者就可以避免计算大的中间数字。 - wally
1
@wally -- 你的发现很好。我没有考虑到这些对数函数具有任何特定的底数,因为它们是在比率中,并且在推导中b不一定是10。在这里选择基数10的方便性只是逃脱了我的注意力。请注意,log有时表示log<sub>e</sub>ln;我尤其注意到这一点在旧的数学参考文献中。 - ad absurdum
1
多好的解释。谢谢你。你的回答让我意识到我的书里的解释有多糟糕。 - Peter Chaula
1
@peter -- 谢谢。我在几年前回答这个问题时,它已经很老了;很高兴知道有人仍然觉得它有用 ;) - ad absurdum
这适用于任何基数 $q$ 转换为基数 $p$。 - Eduardo Sebastian

3

如何确定表示数字所需的位数的技巧是这样做的。您有R个符号用于表示,并且想知道需要多少位,解决此方程式 R=2^n 或 log2(R)=n。其中n是比特数,R是表示中的符号数。

对于十进制数字系统,R=9,因此我们解决9=2^n,答案是每个十进制数字需要3.17位比特。因此,一个三位数需要9.51位或10位。一个1000位数字需要3170位。


4
对于十进制系统而言,R=10。你需要20位来表示6位数字,而不是19位,即每个数字需要3.32位。 - stark

1
假设问题是询问存储3位数所需的最小位数,
我的解决方法如下:
1.需要存储的最大3位数是多少?答案:999
2.我需要存储这个数字的最小位数是多少?
可以通过反复将999除以2来解决此问题。然而,使用数学的力量来帮助我们更简单。本质上,我们正在解决以下方程式的n:
此问题可通过以下方式解决:
2^n = 999
nlog2 = log999
n ~ 10

你需要10个二进制位来存储一个三位数。用类似的方法来解决其他子问题!希望这能帮到你!

1
简短的答案是:

int nBits = ceil(log2(N));

这是因为pow(2, nBits)略大于N。


0

对于一个n位二进制数,它所能表示的最大十进制值为

2^n - 1,而2^n是使用这么多位数字可以生成的总排列数。

以只想要三个数字的情况为例,即您的情况1。我们看到要求是:

2^n - 1 >= 999

对两边应用对数:

log(2^n - 1) >= log(999)

log(2^n) - log(1) >= log(999)

n = 9.964(约)。

由于9.964不能是有效的数字位数,因此取n的ceil值,我们得到n = 10。


0

将数字不断除以2,直到得到商为0。


0

最简单的答案是将所需值转换为二进制,并查看该值需要多少位。然而,问题要求X位十进制数需要多少位。在这种情况下,似乎必须选择具有X位的最高值,然后将该数字转换为二进制。

作为一个基本示例,假设我们想存储一个1位十进制数,并想知道需要多少位。最大的1位十进制数是9,因此我们需要将其转换为二进制。这产生了1001,共有4位。这个例子也适用于两位数(最大值为99,转换为1100011)。要解决n位数,您可能需要解决其他问题并寻找模式。

要将值转换为二进制,您需要重复除以2,直到获得商为0(所有余数都为0或1)。然后,您需要颠倒余数的顺序以获取二进制数。

例如:将13转换为二进制。

  • 13/2 = 6 余 1
  • 6/2 = 3 余 0
  • 3/2 = 1 余 1
  • 1/2 = 0 余 1
  • = 1101 ((8*1) + (4*1) + (2*0) + (1*1))

希望这能帮到你。


它适用于前两个问题,但当你来到下面两个问题时,它们足够大,需要用你的方法来解决。 - user379888

0

这个可以工作!

floor(loge(n) / loge(2)) + 1

为了包含负数,您可以添加一个额外的位来指定符号。

floor(loge(abs(n)) / loge(2)) + 2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接