비트는 메모리에 어떻게 저장됩니까? (청크에서? 여러 가지 크기의 비트가 도로 저장 될 수 있습니까?)

StackOverflow https://stackoverflow.com/questions/1546381

문제

나는 각 메모리 위치에 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

공간을 제외하고는 모두 잘 보입니다. 8 대신 6 비트가 있습니다. 이제 모든 정보가 메모리에 어떻게 저장되는지 궁금합니다. 모든 것이 8 비트 덩어리에 저장된 경우

안녕하세요 : 1001000110011111110011011001101111

그런 다음 각각 8 비트 청크를보고 어떤 숫자를 나타내는 숫자 (그리고 어떤 ASCII 코드를 참조하는지)를 알아낼 수 있습니다. 6 비트 공간과 4 비트 /N과 같이 다른 크기의 캐릭터가 그들과 함께 저장 될 때 어떻게 작동합니까 ?? 그렇다면 큰 공간에 소수를 저장하지 않습니까?

나는 기본적인 이해가 잘못되었다고 생각합니다 (또는 프로그램이 어딘가에 잘못되었습니다 ...). 질문이 이상하거나 불필요하게 심도있는 소리로 들리면 죄송합니다. 나는 단지 알고 싶다. 나는 인터넷 검색을했지만 관련성이없는 것은 없었습니다. 내가 어디에서 잘못되었는지 알려 주거나 올바른 방향으로 나를 지적 할 수 있다면, 나는 그것을 크게 감사합니다. 감사!

도움이 되었습니까?

해결책

Java가 아닌 C 및/또는 어셈블리 실험이 더 좋습니다. 이러한 언어는 낮은 수준이며 주소 공간을 직접 노출시킵니다.

나는 각 메모리 위치에 8, 16, 32 또는 64 비트를 포함한다고 생각했다. 따라서 0101은 8 비트 머신에 00000101로 저장됩니다 (부호 인 경우 부호 확장). 이 시스템의 내부 작업을 찾기 위해 호기심으로 Java로 프로그램을 작성할 때까지 이것은 모두 훌륭하고 멍청했습니다.

X86 시스템의 모든 메모리 위치에는 8 비트 (1 바이트)가 포함됩니다. 값에 단일 바이트에 맞는 것보다 더 많은 데이터가 포함 된 경우 여러 바이트를 사용하여 저장됩니다. 예를 들어, C에서 "float"유형은 4 바이트 (32 비트)를 사용하여 저장됩니다.

공간을 제외하고는 모두 잘 보입니다. 8 대신 6 비트가 있습니다. 이제 모든 정보가 메모리에 어떻게 저장되는지 궁금합니다. 모든 것이 8 비트 덩어리에 저장된 경우

공간은 단일 바이트에도 저장됩니다. 인쇄 코드는 8 개의 공간으로 패드하는 것을 잊고 있습니다. 100000 == 00100000 == 0x20.

다른 팁

공간에는 8 비트도 있습니다. 그것은 단지 그 정수입니다. Tobinarystring은 선두를 인쇄하지 않습니다 0 당신이 그것을 사용하는 방식을 비트.

모든 선두와 함께 0 비트, 실제로 메모리에서 이렇게 보입니다.

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

원래 직관은 (대부분) 정확했습니다. 모든 메모리 위치는 동일한 수의 비트로 구성됩니다. 모든 현대 기계에는 "바이트"에는 8 비트가 있으며 바이트는 기계가 개별적으로 액세스 할 수있는 가장 작은 메모리 덩어리입니다.

출력을 자세히 살펴보십시오. 당신은 가지고 있습니다 일곱 공간을 제외한 모든 곳에서 숫자. 이 공간은 이진 표현에서 두 개의 0으로 시작하는 반면 다른 글자는 하나로 시작합니다.

실제로 당신의 접근 방식은 잘못되었습니다. 인코딩은 여기서 매우 중요합니다.

ASCII를 사용하는 경우 각 캐릭터가 바이트 (8 비트)에 저장되어 있지만 변경 사항을 인코딩 할 때는 쉽게 말할 수 없습니다.

EG : UTF-8은 문자열의 각 문자에 대해 1 ~ 3 바이트 (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 O : 01101111 : 00100000 W : 01010111 O : 01101111 R : 01110010 L : 01101100 D : 01100100 n : 00001010

당신은 그것을 확신 할 수 없습니다. 파일 시스템은 그렇게 간단하지 않습니다. 어쩌면 Hello는 연속적이지만 World String은 드라이브의 끝에 있습니다. 그것이 Defrag 명령이있는 이유입니다.

그러나 문자열을 정의 할 때 Main Memory (RAM)에 대해 이야기하면 비트가 연속적이라고 기대합니다. 적어도 C에서는입니다. 당신은 그런 문자열을 그렇게 정의합니다.

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

여기 value [0]는 우리의 문자열의 첫 번째 문자입니다. 값은 메모리의 숯 배열 위치에만 주소 만 주소입니다.

값 [0]의 주소가 10이면 값 [1]의 주소는 10+8 = 18입니다.

컴퓨터 저장소 번호는 자동차의 주행 거리계와 비교할 수 있습니다. 주행 거리계에 4 자리가 있으면 숫자 33을 "0033"으로 저장합니다.

만약 누군가가 묻습니다 당신의 마일리지가 무엇인지, 당신은 "Zero Thousone Zero Hundred와 Thrive Three"라고 말하지 않을 것입니다. 기본적으로 Java도 그렇지 않습니다. (당신은 그것을 말할 수 있지만.)

그렇다면 큰 공간에 소수를 저장하지 않습니까?

글쎄,별로. 어딘가에 11000100을 기억했다고 가정 해 봅시다. 컴퓨터는 이것이 11000100 또는 11000, 100 또는 1, 1000, 100 등을 의미하는지 어떻게 알 수 있습니까?

실제로 컴퓨터는 제공되는 프로그램을 따르고 있습니다 (Java 프로그램은 부분적으로 귀하와 부분적으로 Java를 디자인하는 사람들에 의해 만들어 졌음을 기억하십시오). 비트를 저장하기위한 실행 가능한 시스템을 만들 수 있다면 컴퓨터를 수행 할 수 있습니다.

그러나 프로세서 사용 및 프로그래밍 난이도 측면에서 트레이드 오프가 있음을 명심하십시오. 일반적인 컴퓨터는 바이트와 함께 작동 할 수 있기 때문입니다 많이 7 비트 또는 가변 비트 숫자와 함께 할 수있는 것보다 빨리 ASCII 코드를 바이트로 저장하는 것은 텍스트를 저장하는 데 매우 일반적인 선택입니다.

그러나 내가 당신의 질문으로 돌아가겠습니다.

그렇다면 큰 공간에 소수를 저장하지 않습니까?

수학적으로 말하면, 아니요. 수학의 지점 정보 이론 절대적으로 필요한 비트의 수는 인코딩하고자하는 가능성과 각각의 가능성에 달려 있다고 알려줍니다.

4 개의 문자 알파벳 (A, B, C, D) 만 있다고 가정 해 봅시다. 각각 2 비트 번호 (각각 00, 01, 10, 11)를 사용하여이를 나타냅니다. 이 문자 각각이 똑같이 가능할 가능성이 있다면 문자 당 필요한 최소 비트 수는 2입니다. 아니요 a가 00이고 b가 01이지만 낭비되는 비트.

반면 ASCII를 사용하고 A, B, C, D를 다음 7 비트 숫자로 사용하는 경우 :

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

그런 다음 문자 당 5 비트를 "낭비"하고 있습니다 ( "큰 공간에 작은 숫자를 저장하지 않더라도").

이러한 종류의 고려 사항은 압축 알고리즘을 설계 할 때 중요하며 Everday Applications에서는 중요하지 않습니다. C를 배우려면 비트와 바이트를 이해하는 것이 중요합니다.

에 따르면 Java 4 API,

서명되지 않은 정수 값은 인수가 부정적인 경우 인수 + 232입니다. 그렇지 않으면 논쟁과 동일합니다. 이 값은 이진 (기본 2)의 ASCII 자리 문자열로 변환됩니다.

실제로 데이터 저장소는 실제로 훨씬 더 복잡합니다. 처리의 효율성의 경우, 대부분의 데이터 유형은 워드 바운스에 저장되며, 이는 32 비트 머신의 4 바이트 또는 64 비트 머신의 8 바이트를 의미합니다. 배열은 더 밀접하게 포장 될 수 있으므로 char [4] 같은 양의 "실제 공간"을 사용하여 char.

Java는 가상 머신이며 어떤 메모리 아키텍처가 사용하는지 확실하지 않습니다.

그것은 그것을 정리합니다. 나의 주요 문제는 내가 처음에 0을 내려다보고 있다는 것이었다. 압축 알고리즘 (즉, GZIP)에 대해 더 많이 읽을 때 이것을 실험하고있었습니다. 표현을 보는 것은 프로그램의 목표가 아니었지만 단어 당 다른 비트 수는 내가 작업중 인 파일 유형에 대한 기본 인덱스 기반 압축을 구현하는 원래 목표에서 나를 버렸습니다. Java에 개념 증명이 있으면 C로 다시 작성하려고합니다.

감사!

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/integer.html#tobinarystring%28int%29
Integer.tobinarys의 사양은 다음과 같습니다.

"이 값은 이진 (기본 2)의 ASCII 자리 문자열로 변환됩니다.

당신 이이 사실을 간과 한 것은 당신의 혼란을 초래 한 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top