블로그 이미지
플래시로 밥먹고 살고 있습니다... 하지만 여긴 플래시 전문 블로그가 아닌 그냥 개인 블로그랍니다
미나토

Recent Comment

calendar

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      
  • 56,002total
  • 9today
  • 173yesterday
2012/01/13 17:46 Flash Platform


새해 첫 포스팅입니다... 뭔가 야심차게 한번!!!



서로 문제 없이 프로그래밍을 했는데 문제가 있다???
 


클라이언트와 통신으로 숫자를 주고 받던 도중 이상한 값들이 들어와서 한동안 헤맸던 적이 있습니다...

아무리 확인해도 애초에 잘못된 값이 들어오는데, 클라이언트는 아무리 확인해도 제대로 된 값을 던져줬다는 것이지요...

이것이 다 서로의 언어에 대한 몰이해에서 시작된 것입니다...


Number, int, uint 플래시에서는 이렇게 세가지의 숫자 타입을 가지고 있습니다

uint 는 32bit 형의 정수형이고, int 는 32bit의 부호가 있는 (음수, 양수) 정수형입니다...
그러다 보니, int는 부호에 1bit를 나눠주느라 31bit (2^31 - xor 연산자 말고 승수요) 만을 사용합니다...

as2에서는 Number 형만 가지고 있습니다...


자 이제 Number 에 대해서 알아보겠습니다... 레퍼런스를 보니 53bit 를 사용하고 있다고 합니다.(http://help.adobe.com/ko_KR/FlashPlatform/reference/actionscript/3/Number.html)

하지만 이중에서 하나는 부호입니다... 그러니 실제로는 52bit 만을 숫자에 활용합니다... 그런데 뭔가 이상하지 않나요? 프로그래밍인데 2의 승수인 32bit도 아니고, 64bit도 아닌 52bit 라니 말이죠...

이건 뭔가 이상합니다...

결론부터 말씀드리자면 사실 플래시의 Number는 64bit를 사용하고 있습니다...





실수를 메모리에 어떻게 표현할 것인가...


실수를 64bit라는 메모리에 표현하려면 어떻게 해야할까요... 간단하게 생각하면 1bit 부호 + 32bit 는 정수 + 31bit는 소수로 하면 될 듯 합니다...

그런데 그러고 보니 실수의 표현 범위가 너무나 작은겁니다... 그럼 1024bit쯤 할애하면 되잖아!!! 라고 말할 수도 있겠지만... 프로그래밍의 세계가 우리가 원하는 대로 해줄만큼 만만치가 않습니다.

그래서 생각하게 된 것이 실수를 정수처럼 일단 표현하고 그 뒤에 소수점을 찍자는 겁니다...

123456789 쓰고선 첫번째에 찍으면 .123456789 가 되고, 다른데 찍으면 123456.789 도 되는 것이죠...

뭔가 아이디어는 좋은 거 같은데 중요한 것이 하나 빠졌습니다... 소숫점을 몇번째에 찍을 것인가에 대한 데이터는 그럼 어디에 저장해야 하나요???

그래서 컴퓨터에서 사용하게 된 것이 이진법을 밑수로 한 부동소수점 표기법입니다...
(전 솔직히 이 용어를 누가 지었는지 모르겠지만 불만이 많습니다... 일반적으로 한국 사람이 "부동" 이란 자를 생각하면 "不動" 을 생각하지 않나요???)



실수의 부동소수점 표기방법 

이진법을 밑수로 한 부동소수점 표기법...... 뭔가 되게 이름이 길지만 결국 다음과 같습니다...

0.4 = 0.8 * 2^(-1) 이 됩니다...
0.4 = 1.6 * 2^(-2) 도 물론 성립합니다...

이처럼 첫번째 숫자를 2(밑수) 밑의 수로 만들어 표현한 것을 정규화라고 합니다... 이걸 왜 하냐면... 무조건 1로 만들어준다는건 생략할 수도 있다는 말이고 그만큼 한자리를 더 표현할 수 있기 때문입니다...

1bit는 부호에 사용한다고 했습니다
52bit가 Number 의 범위라고 했지요... 자, 나머지 11bit는 바로 여기에 있습니다... 2의 - 승수입니다...

이에 따라 2진연산 오차도 생기는 것인데...  당연하게 52bit 이상을 실수에 쓰면 오차가 생기는 것이지요. 말했잖아요.... 52bit까지밖에 못쓴다니까요???
as3로 trace(1.3 - 1) 를 찍어보세요... 0.3을 기대하셨다면 안타깝다는 말씀밖에는 드릴 말이 없습니다...
제가 찍어보니 0.30000000000000004 가 나오는군요...


뭐 더 자세한건 위키백과를 찾아서 봐주세요... 이 포스팅이 이걸 얘기하려고 하는 것은 아니니까요...
부동소수점에 대한 글을 쓰려는게 아니라 통신에 대해 쓰려는 겁니다...




각 언어에서 지원하는 숫자타입


암튼 플래시에서는 저렇게 숫자를 사용합니다만... 다른 언어는 어떤가요...

전 플래시 말고는 배워본 적도 없는 비전공자이지만 여러 숫자타입이 있다는 것은 어깨너머 들어서 알고 있습니다... 그리고 같은 실수 표현법에도 플래시의 부동소수점 표기법에 따라 결과가 달라질 수 있습니다...



클라이언트에게 제가 인자를 던져달라고 할 때, 이렇게 말했습니다...

"숫자로 던져주세요..."

이제 게임회사 개발자로서는 이건 틀린 커뮤니케이션 방법이 된겁니다...
클라이언트가 52bit 이상의 숫자를 던져준다면??? 이정도까지 숫자를 쓸 일이 없다고요???

리니지 서비스한 지가 십수년이 흘렀죠??? 지금까지 모은 아덴이 있다면 얼마일 것 같나요???

만약 제가 누군가에게 우편으로 돈을 보냈는데, 플래시의 이진연산 오차로 잘못된 값을 보냈다면???
패치할때까지 게임서버 내리고... 버그를 찾아 찾아... 누구에게 책임이 돌아올까요???


단위가 매우 늘어날 수 있는 숫자타입은 차라리 String으로 던져주는 것이 안전합니다... 라고 결론을 내고 끝내고 싶은데...




그럼 뭘로 주고 받아야 하나요???


클라가 꼭 플래시처럼 문자열을 쓰란 법이 없습니다... 플래시는 문자가 아닙니다. 문자열입니다...
문자는 16bit 이고, 그에 따른 배열이란 말입니다.

바로 Vector.<int16> 이런걸 상상해보시면 딱 맞습니다...

여기에 관해서는 제가 참여한 e-book 을 보시면( http://itunes.apple.com/us/app/id456620773?l=ko&ls=1&mt=8 ) 홍보 한번!!!

c언어에서는 플래시처럼 vm이 알아서 메모리를 마구마구 늘려주는게 아니고 개발자가 다 잡아놓고 써야합니다...
플래시로 말하자면 위에 쓴 가상의 Vector.<int16> 가 fixed = true 가 된 것이죠...

만약  Vector.<int16> (4, true) 의 형태로 문자열을 잡아서 통신을 했다면 들어올 숫자는 딱 네자리인 셈입니다... 숫자로 주고 받는 것보다 더욱 최악의 상황이 벌어져버린 거죠...




그래서 어쩌라고??


길어지니 결론을 말하라고요???

상황에 맞게 얼마나 주고 받을지에 대해 미리 정의가 있어야 합니다..... 가 결론입니다... :^)
이게 사실 서버와의 통신이라면 데이터를 줄이기 위해 당연한 일인데, 클라이언트와의 통신은 그걸 잊어버립니다.


저같이 전산 비전공이고 플래시만 공부한 사람은 이런 이론적인 것에 대해 많이 모르기 때문에 이런 문제가 닥쳐도 그냥 미지의 버그로 남게되는 경우가 있습니다.
실제로 제가 처음 이진연산 오차를 접하고선 버그리포트로 올린 적이 있답니다...ㅡ.,ㅡ;;;

하지만, 게임 회사는 에이전시처럼 플래시만으로 뭔가가 돌아가는 회사가 아닙니다... 타 언어와의 통신은 필수입니다...

그렇다면, 타언어로 프로그래밍까지는 못하더라도... 어느정도의 이해는 필요한 것이죠...




참고 :

http://help.adobe.com/ko_KR/FlashPlatform/reference/actionscript/2/help.html?content=Part2_AS2_LangRef_1.html 

http://help.adobe.com/ko_KR/as3/learn/WSf00ab63af761f1702761490412937d6fc9b-7ff5.html 

http://help.adobe.com/ko_KR/FlashPlatform/reference/actionscript/3/Number.html 
 
http://ko.wikipedia.org/wiki/%EB%B6%80%EB%8F%99%EC%86%8C%EC%88%98%EC%A0%90  

http://wooyaggo.tistory.com/category/ActionScript%203.0 

 
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by 미나토
2011/11/07 12:52 Flash Platform


사실 플래시를 만들 때, && 와 || 이외에는 비트 연산자는 거의 쓸 일이 없습니다.


정확히는 쓸 일이 없다기 보다는, 사용하는(그리고 사용할 줄 아는) 분이 별로 없다보니 코드가 어려워보일 수 있기 때문입니다.
써봐야 이북에 썼던 <<, >> 정도죠...


저또한 거의 쓰지 않고 사는데 아무런 지장(?)이 없는데, 쓸 일이 생겼어요... 게임 클라이언트 개발자가 Boolean 데이터를 묶어서 보내면서, ui쪽에 비트검사를 해줄 것을 요구하더라고요...
위와 같은 이유로 거절을 하고, 풀어 쓸까 했는데, 비(非)전산 아이들(?) 교육용으로 그냥 적용하기로 남겨놨습니다.

그러면서 겸사겸사 이번 포스팅을 올립니다. (원래는 앞서 말했듯 미친듯이 바빠서 포스팅 쓸 시간 없어요...)



이건 프로그램을 배우기 전에도 어릴때(중학수준 정도?), 기술(물리였나?) 시간 등에서 배웠던 놈입니다...(요즘은 기술 시간이 멀로 바꼈다던데...) 


 & 는 둘다 두 비트가 1이여야 1을 반환하고, | 는 둘중 하나만 1이여도 1을 반환하고 ~는 반대를 반환합니다
AND, OR, NOT 이죠...

이론은 아실거라고들 생각하고(구글링 하시길...) 도대체 이걸 어따 써먹나에 집중하겠습니다.



이런 데이터가 있다고 치죠...

b0:Boolean = false;
b1:Boolean = false;
b2:Boolean = true;
b3:Boolean = false;
b4:Boolean = false; 


e-book 의 내용을 보셨다면, 이 녀석을 한데이터로 바꿀 수 있다는 걸 아실겁니다. 

b:ByteArray =  00100;
(플래시에 이렇게 쓸순 없지만 이렇게 표현 가능하다고 치자고요...) 
0번째 비트가 b0, 1번째 비트가 b1, 2번째 비트가 b2... 이렇게 표현하여 하나의 변수에 담을 수 있겠죠...


변수가 수십수백개가 될 수 있는걸 하나로 바꿀 수 있다...가 당연히 끝은 아니고요... 이걸 가지고 작업을 해야겠죠...


b2가 true 인지 false 인지 체크해보겠습니다.

자 다시 b를 uint라고 봅시다.
b:uint =  4입니다...

이렇게 비트를 정수로 변환시키고 싶을 땐 윈도우 계산기를 사용하면 편합니다 

 

위처럼 왼쪽의 모드를 바이너리(Bin)로 바꾸고 이진수를 넣은 다음 다른 모드로 바꾸면 4로 바뀌어 있는걸 보실 수 있습니다...(당연히 그 반대도 가능하겠죠)

어쨌든 그래서 4 입니다

&는 인자가 둘다 1이어야 true 라고 했습니다. 그렇다면 b2가 해당하는 곳에 비트가 1인 놈을 같이 & 연산을 한다면 true임을 알 수 있겠죠?

그럼 이런 수라면 가능합니다...
00100, 100... 등 우측에서부터 2번째(0부터 샜을때 실제로는 3번째)가 1이고 나머지는 0인 숫자를 만들어낸다면 됩니다

   00100
&    100
--------
   00100

이 되는 거니까요...


그러면 이제 100을 어떻게 만들어내느냐인데... 이미 우리는 쉬프트 연산으로 쉬운 방법을 알고 있습니다
1 << 2 이렇게 하면 1을 왼쪽으로 두번 밀어주니 100 이 만들어지죠...


결과적으로 이런 코드가 된겁니다


b:int = 4;
trace(Boolean(b & (1 << 2)))

/////

true

이러면 b2가 true 임을 알 수 있게 된거죠... 클라이언트가 하나의 숫자로 수십개의 Boolean 데이터를 던져줘도 비트 인덱스만 알고 있으면 쉽게 계산이 됩니다.


글이 길어져서 |, 나 ~ 는 생략합니다...(정말 바빠요...ㅠㅠ)

하지만 위에것만 이해해도 당장 응용 정도는 할 수 있으리라 믿으면서...!!!!
(이렇게 어렵게 설명해놓고!!!)




흠... 써놓긴 했는데, 사실 아직도 코드 가독성면에서 이런 비트연산법을 가르치는게 맞는지 모르겠어요... 어렵기만 어렵고 잘 쓰지도 않다보니...
말씀드렸다시피 쓸 생각 없었는데 클라가 요구를 해와서 그냥 겸사겸사입니다...

비트 패러티로 설명을 할까 하다가 저도 네트웍쪽은 잘 몰라서... 그냥 이렇게 설명했습니다


뭐, 하지만 모르는 것보단 낫겠죠???



p.s. 설명이 부족한 분은 구글에서 bitmask 를 검색해주세용~
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by 미나토
2011/10/19 02:17 Flash Platform


자, 글을 보기 전에 이 글을 먼저 보세요 (http://ko.wikipedia.org/wiki/%ED%96%89%EB%A0%AC)


자세한 설명은 위 링크에 더 많이 나와있고, 전 실제 Matrix3D가 어떻게 돌아가는지를 살짜쿵 맛보겠습니다. 내용이 많아질거 같아 설명은 링크에 양보하겠습니다.
(Matrix 로 설명을 할까 하다가, 요즘 플래시 11 + 3d 스터디를 시작했기 때문에 Matrix3D 로 설명을 하겠습니다.)

Matrix3D 요소(as 레퍼런스의 이미지를 가져왔습니다)


Matrix3D 는 4*4 행렬을 사용합니다


4 * 4 행렬이기 때문에 총 원소(이 표현이 맞는지 모르겠네요)는 16개가 됩니다. Matrix 와 달리 16개나 되는 숫자를 넣다보니 Vector.<Number> 를 생성자의 인자로 갖게 됩니다.

그리고 Vector 의 원소는 1행의 1열부터 1행2열, 1행 3열, 1행 4열, 2행 1열..... 이런 순서로 채우게 됩니다

예를 들어,

var v:Vector.<Number> =  Vector.<Number>([0,1,2,3,   4,5,6,7,    8,9,10,11,      12,13,14,15])
var m:Matrix3D =  new Matrix3D(v)

이렇게 넣는다면,  

0  4  8   12
1  5  9   13
2  6  10  14
3  7  11  15

이렇게 채운다는 말이죠...

디스플레이 오브젝트의 기본값(scaleX = scaleY = scaleZ = 1, x = y = z = 0)으로 넣는다면

1  0  0  0
0  1  0  0
0  0  1  0
0  0  0  1

이렇게 될겁니다. 맨마지막(그림에서 tw)이 1인 이유는 항등행렬에 만족하기 위해서입니다. 이건 나중에 기회가 되면...

 

자, 이걸 위치를 이동시켜보죠. x, y 를 각각 100 씩 이동시켜본다고 하면...

1  0  0  100
0  1  0  100
0  0  1  0
0  0  0  1 

이 되어야 한다는 겁니다


하지만 이런걸 대신 해주는게 바로 Matrix3D 입니다. 여러가지 행렬연산을 해주는 메소드들이 있죠... 예를 들어 위치이동이라면 appendTranslation($x:Number, $y:Number, $z:Number):void 이 바로 그놈입니다


var a:Matrix3D = new Matrix3D();
a.appendTranslation(100,200,300);
trace(a.rawData);

//////////////////////////

1,0,0,0,0,1,0,0,0,0,1,0,100,200,300,1

이렇게 나온단 얘기입니다... 이 외에도 많은 메소드 들이 있는데 그 녀석들이 복잡한 행렬연산을 대신하기 위해 있습니다.




뭐, 어렵죠? 저도 어렵습니다

그러니 어려운 행렬 계산은 컴퓨터에 맞기고, 우리는 3d 공부나 하는 것이... 아 3d가 더 어려운가...

암튼 내용이 길어지니 오늘은 Matrix3D 맛배기만... (사실, 저도 행렬을 잘 몰라 공부하며 쓴거라... 더 공부해야 2편을 쓸 수 있다는...)


p.s. 웬지 써놓고 보니, 자주 쓰이는 플래시 수학은 아닌듯하다는... 게다가 스터디에도 딱히 필요 없을 것도 같다는...


 
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by 미나토
2011/10/19 00:42 Flash Platform


밤을 새다보니 또 쎈치해져서 포스팅을...


π 많이 쓰죠... 원주율이라고도 하고 파이라고도 하고... 암튼 많이 씁니다.


한 20 여년전(쯤??) 수학책에서는 지름이 1인 원의 둘레를 실로 재니 3.14 어쩌고가 나와서 그걸 π 라고 부른다고 했던게 어렴풋이 기억이 납니다...

π는 결국 어떤 비율인 상수값인 셈인데, (그래서 히카님은 그냥 이렇게 사용한다고 하십니다)

지름 * π = 3.14.....

지름이 1이라고 했으니 결국

π = 3.14.....

가 된 셈입니다...


지름이 1일 때, 원의 둘레가 π 이니, 반지름을 r 이라 치면

2 * r * π
즉 반지름이 r일때, 2πr이 둘레가 된것이지요


웬지, 쓰다보니 앞선 Math.PI * Θ / 180 하고 순서를 바꿨어야 할 것 같은데... 뭐 어쩌겠습니까... 제가 책을 쓰는 것도 아니고...



내용이 1번 포스팅에서 설명됐어야 하는 것들인데... 그냥 이렇게 올리게 되네요... 별거 없어서 그냥 1-1 로 올립니다



p.s. 쓰다가 뭔가 잘못된게 있을까봐 좀 찾아보니 차라리 이걸 보는 것이... ㅡ.,ㅡ;;;
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by 미나토
TAG π, 원주율
2011/10/15 03:20 Flash Platform



0, 1 이라고 쓰면 무슨 생각이 드시나요... 전산전공자라면 bit 가 생각나시겠지만, 그걸 쓰려고 하는게 아닙니다. 0 과 1의 의미를 보려는 거죠...


0이란 참 독특한 존재입니다. 어떤 수와 곱하든 결과를 0으로 만들어버립니다.

1또한 독특합니다. 어떤 수와 곱하든 결과를 곱한 수 그대로 보여줍니다.



이 두 수의 이런 특징으로 인해, 이 두 수는 범위 값을 표현하는데 자주 쓰이게 됩니다...

모든 범위는 0 에서 1까지의 수로서 표현이 가능합니다. 




as2 에서 as3 로 언어가 바뀌면서, 많은 것들이 변했는데(이제는 너무 옛날 얘기죠...) 그중에서 Movieclip 의 alpha, scale 등의 속성이 0~100 에서의 범위가 아닌 0~1 의 범위로 바뀌게 되었습니다...

이는 알게 모르게 연산의 편리함을 줬습니다. 예를 들어보죠...


mc(Movieclip ) 안에 childMC 라고 또다른 mc가 있다고 쳐보죠...

mc를 두배 크게 하려면, as2에서는

mc._xscale = 200;

라고 할겁니다. 그런데 이때 자식인 childMC 는 크기를 그대로 유지하고 싶다고 하면 어떻게 해야할까요... 반대로

childMC._xscale = 50;

을 줘야합니다

그런데 이건 미리 정해진 상수이고 원하는 스케일의 변화가 변수라, n배 커지고 싶다고 한다면

mc._xscale = n * 100;
childMC._xscale = 100 / n;


이제 1로 바꼈으니 간단합니다.

mc.scaleX = n;
childMC.scaleX = 1 / n;

식만 간단해진 것이 아니라, 곱셈연산도 사라졌기 때문에 연산도 빨라지게 됩니다. (타이핑이 줄어드는 것도 있다는!!!)


0 에서 100 또는 1이 아닌 그 어떤 수 n 이였다면, 어떤 비율을 곱하는데 있어서 항상 곱셈연산이 따르게 됩니다만, 1은 결과값이 그 수 그대로이기 때문에 수학식으로는 1을 곱하는 것이 맞더라고 결과적으로 그 수를 그대로 써주면 되는겁니다.


그리고 이런 장점은 확장성에서도 나타납니다.

플래시는 argb 칼라를 씁니다 (alpha + red + green + blue)

현재는 0xFFFFFFFF 이런 16진수 체계를 사용하지만, 만약 앞으로 플래시가 각각의 칼라값을 더 다양하게 표현할 수 있다고 해보죠... r = 0xFF 가 아닌 0xFFFF 까지 표현할 수 있다고요...
그럼 플래시의 색재현력은 더욱더 뚜렷해질 것이고, 섬세한 그라데이션을 표현할 수 있게 되겠죠...

그런 업데이트가 일어나면 우리는 색 값을 모두 바꿔줘야 할겁니다...

하지만 red 값을 0~1 로 표현한다면,0 ~ 0xFFFFFFFFFFFFFFFFF 로 레드값의 범위가 변한다고 해도 저희가 원하는 색상대로 표현이 될겁니다.

범위에 대한 비율값으로 표현을 했기 때문입니다.


암튼 이런 특징은 다양하게 활용할 수 있습니다.

앞서 말한 스크롤에도 위치값이 아닌 0~1 의 범위로 값이 떨어지게 만들면, 가로스크롤의 공식을 세로 스크롤에도 적용할 수도 있죠... 가로 세로 만들때마다 항등식을 세로 만들어 줄게 아니라 범위값에 대한 비율을 던져주도록한다면 말이죠...


암튼 머리가 나쁘면, 손발이 고생합니다... 간단한 산수나 수학을 조금 알아두면 참 편해진다니깐요... 
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by 미나토
TAG 0, 1, 범위
 <PREV 1 2 3 4 5 ... 21    NEXT>