[질문] JAVA 에 관한 초보적인 질문인듯 해서요 정말 죄송합니다

ktj0630의 이미지

안녕하세요 질문을 좀 길게 드릴꺼 같아서 죄송합니다.

여러가지 생각을 해 봤는데.. 도무지 저의 생각이 짧아서

그랬는지.. 이해가 되지 않아서 이렇게 질문 드리는것

무척 죄송합니다. 답변해 주실수 있으시면 부탁좀 드릴께요 .

질문 ----

데이터 형에서의 I/O Casting 에 대해서 질문좀 드릴까 합니다.

데이터 형에서의 int 는 4 byte이며, big - endian 형식의 2의 보수

라고 정의 되었습니다. (4byte 32 bit ) 이겠지요 ..

그럼 Byte 의 데이터 형은

1byte 이며, 8bit 이겠지요 ? 그런데.. 이 Data 형식에서의

Byte 는 숫자의 범위가 -128 에서 127 사이의 범위를 가집니다.

따라서 128, 129 같은 정수는 Byte 타입에서의 적절한 값이 아니란

소리인데요 ..

일련의 I/O 작업에서요 ... read(), write() 를 사용하는 경우에서는요,

이런 많은 메서드 들이 Byte를 사용하도록 되어 있습니다.

예를 들어서

public abstract int read() throws IOException

이 메서드를 볼 경우에는요 ...

이것은 추상 메서드 이므로 Sub Class 에서 명시적으로 구현을

해서 사용을 해야 한다는것으로 생각이 되거든요 ...

그런데.. 다른 한편으로

public int read(byte[] data) throws IOException

public int read(byte[] data, int offset, int length) throws IOException

이 두가지 메서드가 byte 타입의 배열을 읽고 쓰는 실례를 보여 준

메서드 거든요 ..

그런데 질문은 byte 데이터 형식은 정수 범위가

-128 ~ 127 이라는 범위를 가지고 있습니다.

그런데 실례적으로 이런 메서들 read(), wrtie() 등은

데이터를 읽고, 쓰는 것에서, 리턴하는 타입은

부호가 없는 (0~255) 까지의 범위를 가지는 int 라는 소리를

들었습니다.

메서드에서도 선언을 이런형식으로 데이터 리턴형을 이렇게

주었구요..

public int read(byte[] data) throws IOException

public int read(byte[] data, int offset, int length) throws IOException

그래서 여기서 사용되는 int 타입은 0 에서 255 까지의 부호가

없는 정수라고 알게 되었습니다.

그런데..

질문 1)

만약 부주위한 프로그래머들이 프로그램을 작성하는 시에

0~255 사이의 값을 갖는 부호 없는 바이트 범위를 벗어난

경우에서는 이런 경우에서는

상위 24비트는 무시 되고

8개의 상위 비트는 출력이 된다고 했습니다.

음 어떤형식으로 상위 24비트가 무시되는지가 궁금해 지네요 ?

이것은 다른 만약 int b 라는 정수를 256 값으로 나눈 나머지를

취하거나, 값이 음수인 경우에는 256을 더하는 효과를 준다고

한다고 하거든요 ...

식으로 표현하면

b = b % 256 >= 0 ? b % 256 : 256 + b % 256 ;

이런 형식이라는데 이 식이 어떤 것을 의미하는지가

궁금합니다.

질문 2)

어떤 한 숫자에 관해서는 8비트의 byte 타입이나, 32 비트의 int 타입이

중요하지 않을꺼지만, 수천 수백만개의 숫자를 읽게 된다면

아마도 굉장한 문제가 일어날듯 합니다.

그래서 실제로 VM 에서는 내부 하나의 Byte 타입을 4byte 공간을

차지하자만 byte[]에서는 필요한 공간만 차지한다고 익혔습니다.

음 실례 메서드는요 ...

public int read(byte[] data) throws IOException

public int read(byte[] data, int offset, int length) throws IOException

이런 byte[]를 받는 read()의 경우에서는

필요한 공간만 차지하게 된다는 소리인데요 ... ?

그럼,, VM은 byte[]을 다루는 특수한 명령을 차지하고

있다는 소리이거든요 .. 아마도 그렇게 설계가 되었을꺼라고

믿거든요...

하지만 이렇게 단일 byte[] 는 처리하는 명령은 가지고

있지 않다고 들었습니다.

이런 한가지의 byte[]는 int 타입으로 확장해서

변환을 시켜야 한다는 소리인데...

데이터가 배열에 저장될때, -128 에서 127 사이의 범위의

숫자이겟지요 ?

byte형을 받으니깐요 ,, 그런데..

I/O 작업에서는요, 자바가 부호가 있는 바이트 형태로 저장이

된다고 해도, 이러한 부호가 있는 값과, I/O 에서 사용되는

부호가 없는 바이트 사이에서는 다음의 주어진 식처럼

단순한 일대일 대응이 일어난다고 하는데..

도무지 256 이 어떤 수를 의미하는지를 모르겠습니다.

int unsigneByte = signedByte >= 0 ? signedByte : 256 + signedByte;

죄송합니다.

정말 길게 질문을 드려서요 ...

한가지만 더 드리겠습니다.

질문 3)

< 인용구 >

인용을 했습니다.

"byte 타입은 매우 작은 범위를 가지고 있기 때문에 ....

계산에서는 보통 int 타입으로 변환되어서 계산이 되어진다.

때에 따라서는 역으로 변환이 되어질 필요가 있지만...

그렇기 때문에 형 변환이 일어나는 방식을 정확하게 알고 있는것은

매우 가치 있는 일임에는 믿어 의심하지 않는다.

int 에서 byte로 캐스팅은 (범위가 넓은 정수에서 ---> 좁은 범위)

로 캐스팅이 되어지는것이 분명하듯이 ...

상위 바이트를 잘라냄(truncation)으로 이루어진다.

이것은 넓은 의미에서는 타입의 값이 범위가 작은 타입의 값으로 표현

될수만 있다면 그 값은 변하지 않는다는것을 뜻한다.

int 127 이 byte로 캐스팅 되어도 ... 그 값은 여전히 127이 된다는 소리이다.

반면에...

int 타입의 값이 byte타입의 범위에서 너무 큰 값을 가지고 있다면...

이상한 일이 발생하기도 한다.

int 128을 byte로 캐스팅 한다면,,, 그 값은 가장 근접한

바이트 값인 127이 되지 않고 ... -128이 된다.

이러한 일은 2의 보수 연산을 통해 이루어진다.

128을 16진수로 나타내면...

0x00000080이다. 이 int 타입의 숫자가 byte로 캐스팅

될때... 앞자리에 오는 0이 모두 사라지고 ...

0x80이 남는다. 이 값을 2진수로 나타내어본다면...

10000000이 된다 이것을 만약 부호 없는 숫자라면

2진수 10000000은 128이 되어 별 문제 없겠지만...

이것은 부호 없는 숫자가 결코 아니다.

오히려 최상위 비트는 부호를 나타내는 비트로써

1은 예를 들어보면... 2의7승을 나타내는것이 아니라...

음의 부호를 나타내는 것이다.

음수의 절대 값은 보수(각 비트의 1은 0으로 0은 1로 )바꿈을

구하고 거기에 1을 더하여 얻을수 있다...

1000000의 보수는 01111111이고 여기다 1을 더하면...

01111111 + 1 = 10000000 = 128(10진수이다.)

따라서 주의깊게 봐야 할것은 ...

실제로

byte 0x80은 실제로 -128을 나타낸다.

비슷한 계산으로 int 129를 보자...

int 129는 byte로 -127로 캐스팅 되고 ,,,

int 130은 byte로 -126로 캐스팅 된다.

이러한 계산은 byte -1로 케스팅 되는 int255까지 적용된다.

숫자가 256이 되면, int 타입은 하위의 (low-order) 바이트는

모두 0으로 채워진다.

이 부분에서 로워 바이트가 0으로 채워진다는것이

어떤 의미인지를 모르겠습니다. ?

다시 말해서 256은 16진수로 0x00000100이다.

이 값을 바이트로 캐스팅 하면, 0이 되고 새로운 주기가 다시

시작된다..

이러한 과정은 다음과 같은 식으로 알고리즘화 할수 있다.

예제)

int byteValue; //변수 선언 ...

int temp = intValue % 256;

if ( intValue < 0 ) {

byteValue = temp < -128 ? 256 + temp : temp;

}

else {

byteValue = temp > 127 ? temp - 256 : temp;

}

"인용끝

질문 3)

여러가지에서 공통된 질문이지만.

256의 용도를 모르겠습니다.

int byteValue; //변수 선언 ...

int temp = intValue % 256;

if ( intValue < 0 ) {

byteValue = temp < -128 ? 256 + temp : temp;

}

else {

byteValue = temp > 127 ? temp - 256 : temp;

}

왜 256 을 더해주고, 빼주어야 하는지를요 ..

또한 위에서도 질문 드렸지만, 데이터 형식의

byte는 -128 에서 127의 범위를 가지는 정수이지만,

I/O작업시에서의 메서드에서에서의 리턴하는 값은

0 ~ 255 사이의 부호가 없는 정수인데,

int unsigneByte = signedByte >= 0 ? signedByte : 256 + signedByte;

이렇게 부호가 있는 정수라도 , 바이트 형태로 저장이 되어도

public int read(byte[] data) throws IOException

이것을 전부다 부호가 없는 I/O의 바이트에서 일대일 대응이

된다는 소리인데요 ...

int unsigneByte = signedByte >= 0 ? signedByte : 256 + signedByte;

256의 용도가 궁금합니다.

또한 Casting을 할때에도 256을 사용한 알고리즘을

나타내었는데요 ..

Byte Casting 알고리즘

int byteValue; //변수 선언 ...

int temp = intValue % 256;

if ( intValue < 0 ) {

byteValue = temp < -128 ? 256 + temp : temp;

}

else {

byteValue = temp > 127 ? temp - 256 : temp;

}

도대체 왜 256을 넣어주고 빼주는지가 ...

죄송합니다. 길게 적어서요 ...

몇일 고민해보다가 혼자서 힘들어서 이렇게 여쭤 보거든요 ...

답변해주실수 있으시면..

정말 정말 감사드리겠습니다.

죄송합니다. 길게 질문 드려서요 ...

좋은 하루 되세요 ...

wooix의 이미지

흐흐.. 글이 너무 길어서 다 못읽었는데용 대충 이거 물어 보신거 같아서 그냥 끄적여 봅니다.

32bit에서 -128이 어떻게 표현되는지는 아시겠지요?
8bit 에서 -128은 다음과 같습니다.
1000 0000
sign extend 해서 모양이 이런식으로 나오지요..
11111111 11111111 11111111 10000000
128이라면
00000000 00000000 00000000 10000000
이고용..

int unsignedByte = signedByte >= 0 ? signedByte : 256 + signedByte인데..

예로 signedByte가 -64라면..
11111111 11111111 11111111 01000000인데..
256을 더해버리면
00000000 00000000 00000000 01000000이고 양수 64를 뜻하네용..
부호가 바뀌는 거죠...
심심하면 다른 수도 해보세용..

인용구는 길어서 보기 싫어서 안봤습니당.. ^^;;

딴거도 이거랑 비슷한거 같은데 그냥 연필로 그적거려 보시길...

평온하다~

ktj0630의 이미지

ㅎㅎㅎ
너무 감사드립니다.

죄송해요 ....

다른생각을 하다가 올려주신 글구를 읽어보니...

제가 또 다른생각으로 좀더 복잡하게 생각을 하고 있었구나...

하는 생각에 정말 부끄럽네요 ...

사실 비트 연산까지 해보면서 이걸 왜 이렇게.. 표현을 했을까 ?

하는 생각에 여러가지로 부족한 제 자신을 자책하고

그랬는데...

정말 감사드립니다.

일련의 I/O 작업에서의 별로

다른 분들은 기존의 I/O작업의 API를 주의 깊게

보시는 분들이 적더라구요 ....

그냥 NetWork 에 관한 공부를 하면서....

의문이 생겼는데...

막상 찾아보면서 생각을 해보니...

작은 질문이였지만.. 정말

감사드립니다.

배려있는 설명도 정말 너무 나 감사드립니다.

여러곳에 Posting을 사실 해서 여쭤 봤는데...

사실 JAVA 포탈에서도 답변이 나오질 않더군요 ....

하지만 Kldp에서는 여러모로 개발자님들이 많이 포진하시고

있으셔서 그랬는데... 질문을 드리는것도 사실 부끄럽고 ...

죄송해서 망설이다 질문을 드렸는데...

정말 답변 너무나 감사드립니다.

좋은 하루 되시구요 ....

편안 한주 보내세요....

^^

눈 내린 들판길 가운데를 갈 때
모름지기 이지럽게 가지 말 일이다.
오늘 내가 간 자취를 따라
뒷사람의 발길이 이어지느니.....

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.