我曾经认为每个内存位置包含8、16、32或64位。因此 0101 在 8 位机器中将存储为 00000101(如果为负则符号扩展)。这一切都很好,直到我出于好奇用 java 编写了一个程序来了解这个系统的更多内部工作原理。

有问题的方法如下所示:

public void printBinaryRep(File f){
        try{
            FileInputStream inputStream = new FileInputStream(f);
            int next = 0;
            byte b = 0;
            while((next = inputStream.read()) != -1){
                b = (byte)next;
                System.out.println((char)next + " : "+Integer.toBinaryString(next));
            }
            inputStream.close();
        }
        catch(Exception e){System.out.println(e);}
 }

我从一个文件中得到了这个输出,上面写着“Hello World”

H : 1001000
e : 1100101
l : 1101100
l : 1101100
o : 1101111
  : 100000
W : 1010111
o : 1101111
r : 1110010
l : 1101100
d : 1100100

除了空间之外,一切看起来都很好。它有 6 位而不是 8 位。我现在想知道所有这些信息是如何存储在内存中的。如果所有的数据都存储在 8 位块中,例如

你好:10010001100101110110011011001101111

然后,您可以简单地查看每个 8 位块并找出它代表的数字(以及它所指的 ASCII 代码)。当不同大小的字符(如 6 位空间和 4 位 /n )与它们一起存储时,它如何工作?那么在大的位空间中存储一个小数不是会浪费很多位吗?

我认为我的一些基本理解是错误的(或者程序可能在某个地方是错误的......)。如果这个问题听起来很奇怪或者过于深入,我很抱歉。我只是想知道。我已经进行了一些谷歌搜索,但没有找到任何相关内容。如果您能让我知道哪里出了问题或指出正确的方向,我将不胜感激。谢谢!

有帮助吗?

解决方案

您会更好在实验C和/或组件,而不是Java的。这些语言下位,并且直接暴露的地址空间。

  

我曾经认为每个存储器   位置包含8,16,32或64个   位。因此,0101将被存储在一个8   位机为00000101(符号扩展   如果它是消极的)。这是所有罚款   和花花公子,直到我写了一个程序   java的好奇,找出一些   该系统的更内部工作。

在x86系统的所有存储位置都包含8位(1个字节)。如果值包含的数据量超出装入单个字节,它是使用多个字节存储。例如,在C, “浮动” 型的是使用4个字节(32位)被存储。

  

所有的看起来除了细   空间。它有6位,而不是8我   现在不知道如何了这一切   信息被存储在存储器中。如果   这一切被存储在8个块,   像

在空间也被存储在一个字节。您的打印码是忘记拉长到8个空格。 100000 == 00100000 == 0×20。

其他提示

在空间具有8位了。这只是Integer.toBinaryString不打印领先0位你用它的方式。

使用所有领先0位,它实际上看起来像这样在存储器中:

H : 01001000
e : 01100101
l : 01101100
l : 01101100
o : 01101111
  : 00100000
W : 01010111
o : 01101111
r : 01110010
l : 01101100
d : 01100100

您原始直觉是(大部分)正确:所有存储器位置由相同数量的位的。在所有现代机器,有八个位中一个“字节”,其中一个字节是存储器的最小块机器可单独访问。

在你的输出仔细看。您有 7 在所有这些不同的空间位。的空间刚好在其二进制表示两个零开始,而其它字母与一个开始。

其实你的做法是错误的。编码是很重要的位置。

如果您使用ASCII然后可以很容易地说,每个字符被存储在一个字节(8位),但编码的改变的时候可以这么说。

例如:UTF-8使用用于在串中的每个字符一至三个字节(8至24位)。这就是为什么你将看到,可以在其中指定InputStream对象在编码过载。

选择错误的输入流将绝对导致错误串输出。因此,你必须知道该文件,以了解哪些位意味着什么的编码。其实的FileInputStream做这个给你。

如果你存储一个数字串作为其将在硬盘驱动器炭化长度。就像另一个字符。

然而,如果您存储123456789作为字符串ASCII编码将需要9×8位= 72位。

如果您存储此为整数,(请注意,整数的数据宽度的不同在不同的环境中)将只需要16位。

你也不能肯定。

H : 01001000
e : 01100101
l : 01101100
l : 01101100
o : 01101111
  : 00100000
W : 01010111
o : 01101111
r : 01110010
l : 01101100
d : 01100100
\n: 00001010

被存储在硬盘驱动器作为H:01001000 E:01100101 L:01101100 L:01101100 ○:01101111   :00100000 女:01010111 ○:01101111 R:01110010 L:01101100 d:01100100 \ N:00001010

您不能肯定。文件系统并不是那么简单。也许Hello是连续的,但世界的字符串是驱动器的结尾。这就是为什么有碎片整理指令。

但是,如果我们谈论的主内存(RAM)当你定义一个字符串我期望位是连续的。至少在C中,它是。你定义一个字符串那样。

char[100] value; // c is a char array. (there is no string type in c)

这里值[0]是我们的字符串的第一个字符。和值只涉及到在存储器中的字符数组位置。

如果值[0]的地址是10,则值[1]的地址为10 + 8 = 18。

的方式的计算机存储数可以与在汽车的里程表。如果里程表有4位数字,它存储数33为“0033”。

如果有人的询问的您的里程是什么,你不会说“一千零零一百三十三”。默认情况下,Java那样不会。 (虽然你可以告诉它。)

  
    

然后将不存储在一个大的比特空间少量浪费大量的位的?

  

好了,不是真的。假设你有在内存11000100地方。计算机如何应该知道这是否意味着11000100,或11000然后用100,或1,随后1000然后用100,等等?

嗯,其实电脑只是跟随它被赋予的程序(记住,Java程序部分是由你和部分由谁设计的Java的人创造的)。如果你能够在节约位建立一个可行的系统,可以让计算机做到这一点。

但是,请记住,有一个在处理器的使用和编程难度方面的权衡。由于典型的计算机可以与字节工作比它可以与比方说,7位或可变比特数,以字节为单位存储的ASCII码是用于存储文本一个非常普遍的选择更迅速。

不过,让我回到你的问题。

  
    

然后将不存储在一个大的比特空间少量浪费大量的位的?

  

从数学上说,没有。数学的一个分支称为信息论告诉我们,这是绝对必要的比特数取决于你要准备进行编码和他们每个人的可能性有多大。

让我们假设你仅具有四个字母字母(A,B,C,D),并使用两比特(分别为00,01,10,11)的数字来表示它。如果每个这些字母是同等可能的,那么每个字母需要(平均)位的最小数量是2。换句话说,有没有浪费位,即使A是00,且B为01

在另一方面,如果使用ASCII和编码A,B,C,d为以下7位数字:

A: 1000001
B: 1000010
C: 1000011
D: 1000100

,那么你“浪费”每个字母(即使你不“在一个大的比特空间存储小的数字”)。5个比特

这些各种各样的考虑设计的压缩算法时是重要的,而对于应用锁具不那么重要。这当然是重要的,如果你想学习C了解比特和字节。

根据 Java 4 API,

如果参数为负,则无符号整数值为参数加 232;否则,它等于论点。该值将转换为二进制(基本2)中的ASCII数字字符串,而没有额外的前导0。

事实上,数据存储实际上要复杂得多。为了提高处理效率,大多数数据类型都存储在字边界处,这意味着在 32 位计算机上存储 4 个字节,在 64 位计算机上存储 8 个字节。数组可以排列得更紧密,这样 char [4] 最终可能会使用与以下相同数量的“实际空间” char.

Java是一个虚拟机,我不确定它使用什么内存架构(如果有的话)。

这清除它。我的主要问题是,我是俯瞰开始的零。我用这个实验,我正在读更多的压缩算法(即,gzip的) 我是假设ASCII所有这一切。眼看表示不是该方案的目标,但不同的每字位的扔我从为实现我工作的文件类型基本的,基于索引压缩原来的目标。我会尝试重写在C一旦我有概念的Java中的一个证明。

谢谢!

HTTP: //docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#toBinaryString%28int%29 点击 Integer.ToBinarys的规格如下:结果

  

“该值被转换成的ASCII数字串二进制(基数为2)   没有多余的前导零“

这是你忽略了这个事实,是什么导致了你的困惑。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top