[필드와 레코드]

데이터가 의미를 갖는 최소단위를 필드라고 하고, 여러 필드가 모여서 하나의 대상에 대한 자료가 된것이 레코드이다.

이러한 관점에서 구조체를 바라보자.

예. struct student { int id ; double score; } ;

위와 같이 스투던트를 나타내는 자료형을 보면, id 를 나타내기위한 4바이트의 영역과, 점수를 나타내기위한 8바이트의 영역을 합쳐, 총 12바이트짜리 데이터타입이 되는 것이다.

이때 첫 4바이트는 id 를 나타내는 필드가 되고, 두번째인 8바이트는 점수를 나타내기 위한 필드이다.
그리고, student 는 4바이트, 8바이트의 두개의 필드를 갖는 레코드라고 할 수 있다.


-----------------------------------------------------------------------------

[비트필드의 구문]

C에서는 구조체나 공용체를 통해서 사용자 정의형을 만들때, 비트 단위로 필드 폭을 셋팅할 수 있는데, 이렇게 비트 단위로 폭이 셋팅된 멤버를 비트필드(bit-field) 라고 부른다. 즉, 그 레코드의 특정 필드를 나타낸다.

비트필드를 선언하는 구문은 다음과 같다.

bit_field_member  ::= { int | unsigned }1 { identifier }opt : bit_field_width
bit_field_width  
::= nonnegative_constant_integral_expression

즉, 비트필드는 정수형 멤버만 가능하며, 폭은 음아닌 정수만 가능하다.
폭의 최대값은 워드 길이와 같다. 즉, 32 비트 컴퓨터의 경우 맥시멈 32 까지다.
컴파일러는 비트필드들을 최소의 기계 워드로 packing 한다.

----------------------------------------------------------------------------------------------

[비트필드 타입]

비트필드는 unsigned 비트필드와 int 비트필드 두가지가 있다.

unsigned 비트필드는 당연히 영아닌 음수만 저장이 가능하고, int 형 비트필드는 시스템의존적이다.

다음의 예제를 살펴보자.

예.
struct rcd {
unsigned fd1 : 2 ;           // unsigned 비트 필드, 폭 = 2비트
int fd2 : 3 ;                    // int 비트 필드, 폭 = 3비트
} ;


첫번째 비트필드 fd1 은 2비트이므로, 2의 2승 개, 즉 4개의 정보가 저장이 가능하다.
즉, 0, 1, 2, 3

두번째 비트필드 fd2 는 3비트이므로, 2의 3승 개, 즉 8개의 정보가 저장이 가능하지만, int형 이므로, 저장할 수 있는 형태는 시스템에 의존적이다. 어떤 시스템에서는 폭이 얼마건 간에 최상위 비트를 부호비트로 사용한다.

또한, 시스템마다 비트와 바이트를 워드의 상위부터 카운트 하는지, 하위부터 하운트 하는지가 다르기 때문에 비트필드를 사용한 코드를 다른 시스템에 이식할때는 주의를 요한다.

int 형 비트필드를 테스트 해보기 위해 다음과 같은 간단한 코드를 돌려본다.

예.
#include<stdio.h>
typedef struct { unsigned fd1 : 2 ; int fd2 : 3 ; } rcd;

int main(void){
     rcd a={0};           // 구조체 초기화
     int i;

     for(i=0;i<=16;i++)
          printf("a.fd1= %u \t\t a.fd2= %d\n",a.fd1++ , a.fd2++);

     return 0;
}

위의 루프는 각 멤버를 1씩 증가시키면서 배정하고, 출력한다.

아래는 나의 실행결과이다.

사용자 삽입 이미지

즉, 두번재 비트필드 3비트 중에 최상위 비트가 부호 비트로 쓰였음을 알 수 있다.

그래서 011  = 3  다음에 100 = 4 가 입력되었지만, 첫비트가 부호비트인데 오버플로우 되어서 100 = -4 로 해석된 것이다.
마찬가지로, 5 = 101 은  -3 으로, 6 = 110 은 -2 로 , 7 = 111 은  -1 이 되었다. 그리고 이후로 폭을 넘는 값은 잘려서 버려졌음을 알 수 있다.

즉, 현재 나의 환경에서는 int 비트빌드가 32비트보다 작더라도, 음수를 입력할수 있으며, 양수를 오버플로우시켜서 최상위의 부호비트를 변화시켜 음수로 해석되도록 할 수도 있다.

또한, 입력된수의 이진값이 비트필드의 폭을 넘어가는 경우에, 인접한 비트필드로는 오버플로우 되지 않음을 알 수 있다.

---------------------------------------------------------------------------------------------------

[비트필드 얼로케이션]

컴파일러가 비트들을 좌에서 우로 할당하느냐 또는 우에서 좌로 할당하느냐 하는 것은 시스템에 의존한다.
대부분의 컴퓨터에서는 비트필드가 워드 바운더리(word boundary) 에 걸치지 않도록 할당한다.

컴파일러가 비트필드를 어떻게 배치시키는가를 알아보기 위해, 각자 프로그램을 작성해 보자.
다음의 첨부파일은 내가 사용중인 컴파일러가 비트필드를 어떻게 배치시키는가 알아보려고 만들었다.


프로그래밍 팁 : 구조체의 경우는 << 나 >> 연산자로 바로 다룰수가 없다. 그래서, int 형과 함께 공용체로 묶어서 새로운 타입을 정의한후에, 구조체 데이터를 공용체에 배정하고, 공용체의 int형으로 읽어들이면, << 와 >> 로 접근 가능하다. 물론 이것말고도 방법은 여러가지다.

실행화면.
사용자 삽입 이미지


그림을 보면, 첫번째 비트필드 2비트를 최하위에 배치하고, 그다음 비트필드 3비트를 그것의 상위 3비트에 배치했음을 알 수 있다.

따라서, 하위비트부터 차례대로 비트필드를 얼로케이션한다는 것을 알 수 있다. ( 물론 이것은 나의 환경에서 그렇다는 것이다. )

----------------------------------------------------------------------------------------------------

[비트필드 정렬]

앞에서 구문을 보면, identifier 가 option 으로 되어있는 것을 볼 수가 있다. 즉, 사용하지도 않을 비트필드를 지정할 수 있는데, 이러한 이름없는 비트필드는 패딩이나 얼라인(align)을 위해 사용된다.

즉, 빈 공백을 이름없는 비트필드로 메꿔넣음으로 해서, 이후에 사용할 비트필드를 그다음 워드의 앞자리로 이동시키거나 할 때 쓰면 된다.

가령 4바이트 워드에서 다음과 같은 워드를 두개 사용하는 구조체를 고려하자.

struct abc { unsigned i1:7, i2:7, i3:7, :11,                 // 이름없는, 폭11 짜리 비트필드는
                               i4:7, i5:7, i6:7;                      //  그 다음 비트필드가 다음 워드에 오도록 한다.
                };



바로 다음워드에 정렬하는 또다른 방법은 폭이 0 인 이름없는 비트필들르 사용하는 것이다.

struct abc { unsigned i1:7, :0 , i2:7, :0, i3:7 ; };         // :0 은 다음 워드까지 빈필드로 채운다.

이것은 세개의 다른 워드에 세 개의 7비트 필드를 만들게 한다.


-------------------------------------------------------------------------------------------------

앞에서 이미 언급했듯이 구조체 뿐만 아니라 공용체에 대해서도 비트필드를 사용할 수 가 있는데, 구조체, 공용체, 그리고 비트필드를 적절히 조합하면 많은 기술들을 구현할수 있다.

고통에 관하여

Misc.2008. 4. 26. 21:57 |
Smith 말대로, 인간은 고통을 통해서 현실을 인식하는 건지도 모른다. 시험기간만 되면 평소에 보지도 않던 소설책이며 시집이 향기롭게 유혹을 하고, 하고싶은것과 해야하는것 사이의 괴리는 또 얼마나 고통스러웠던가. 하지만 막상 시험이 끝나면 소설책과 시집은 광채를 읽고 다시 먼지가 쌓여가곤 했다.

욕구는 고통이며 희망이고 현실을 인식하는 세포이다. 욕구의 해소는 카타르시스이며 오르가즘이고, 그것은 생각보다 짧다.

어쩌면, 인간에게는 천국이 없는지도 모른다. 시험이 끝나면 꼭 보겠다던 시집이 시험이 끝나는 순간 빛을 잃었던 것처럼, 완벽한 세상역시도 빛을 잃을지도 모른다. 완벽한 세상에 들어선 인간들은 인식의 틀로써 또다시 고통이라는 방법을 택할지도 모른다. 베르테르는 로테를 가지지 못했고 그 고통이 클수록 사랑이란 감정에 대한 인식은 섬세해졌다. 괴테는 죽기전 마지막으로 손녀딸뻘의 여인을 사랑했다. 소녀의 부모는 허락하지 않았고, 그것은 이루어질수 없었다. 괴테의 하루하루는 갈망이 더해갔고, 고통스러웠으며, 삶을 인식하는 세포 하나하나는 섬세하고 날카로워졌다.

고통은 쾌락에 도달하는 하나의 채널이다.

나는 맞는게 정말 싫었는데, 어쩌다 뭘 잘못했던 칠판앞에 나가서 엉덩이를 맞아야 할 때가 있었다. 선생님이 무섭다고 악명이 높은 경우,  오금이 저릴정도의 공포를 맛봐야했다. 그런데 막상 맞고 나면 엉덩이는 얼얼하고 화끈거리고 곧 죽을것 같았지만, 한편으론 "해냈다"와 비슷한 감정을 느끼며, 기쁨이 용솟음치는 것이었다. 특히 맞고나서 제자리로 돌아와 이를 악물고 맞은 부위를 움켜잡으면서 , 아직 맞고있는 녀석들이 괴성을 지르는것을 보거나 다음 맞을 차례를 기다리는 녀석들의 겁에 질린 얼굴들을 보면서 나는 분명 일종의 카타르시스를 느꼈다고 생각한다. 어쩔땐 주체할수없는 웃음이 터져나오기도해서 웃음을 참느라 고생한 적도 있었다.

새디스트적인 쾌락은 그런것인지도 모른다. 고통과 해소, 그 둘 사이의 역학관계. 고통이 클수록 해소되는 순간의 쾌락은 크다. 선생님이 무서울수록 맞고나서 "다맞았다"는 기쁨이 컸던 것처럼... 혼자 좋아하던 사람 때문에 끙끙거릴때, 일생일대의 중요한 시험에서 낙방하였을때... 그러한 모든것들은 욕망과 고통하고 관련이 있다. 이루지 못하는 고통이 큰만큼 욕구가 해소되는 순간 쾌락의 정도는 크다.

무소유의 기쁨은 욕망의 포기이다. 욕망은 고통이라 욕망이 없으니 고통도 없다. 하지만, 욕망이 없으면 해소에 따르는 쾌락도 없다.  곧, 무소유는 고통의 포기이며, 쾌락의 포기이다. 욕망의 해소가 불러오는 쾌락은 강하지만 짧고, 욕망의 포기가 불러오는 기쁨은 길지만 약하다.  욕망이라는 고통에 가득찬 인간의 세포가 날카롭고 섬세한것과는 달리 욕망을 포기한자의 세포는 무디고 둔하다.

dkim의 강의에 무한한 존경을 표해 마지않지만, 오늘 역학 시험은 나로서는 절대로 잘 할 수 없는 스타일의 시험이었고 앞으로도 그럴것 같다. 주어진시간 겨우 2시간, 대충 소문제로 18개인데, 그 소문제들 하나에 질문이 세개씩 있는것도 있고 그래서 문제수는 더 많았다. 근데... 앞뒤로 한장풀었는데, 배점이 5점이드라. 사실 처음문제지를 받아들었을땐, 문제를 쭈욱 훑으니 다 풀어본 내용들이고, 거의다 알겠더라. 근데...이걸 2시간안에 다풀라고? 하는 생각이 드는 순간...문제지에 이런문구가 있더라. You may not attempt to answer all questions. Allocate your time accordingly.

뭐, 아무튼 나로써는 잘볼수 없는 스타일의 시험이었느니 후회는 그만하고... 뭐 나는 내 나름대로 할만큼 했고, 내 신념대로 공부했으니까. 시험은 시험일뿐, 시험때문에 신념을 통째로 버릴필요도 없다. 아니면 마는거다. 내가 원하는 방식의 평가가 아니면 또 어떤가, 이런방식도 있고, 저런방식도 있는거지. 덕분에 이런방식에 능한자는 이런기회에 점수따는거고, 또 다른방식이면 그방면에 소질있는 사람이 점수따면 되지. 박태환이가 달리기 점수 안나온다고 낙심할 필요도 없는거고...하고싶음 하든가. 그냥, 배울수 있는것만 배워가자. 욕심부리지말고... 그거면 족한거 아닌가.

나의 신조 : 차근차근,  꼼꼼히,  제대로 ...                  음... 이러니 잘볼수가 있나 ....


고1때 내 짝이 참 좋아했던 피아노맨.

Billy Joel - Piano Man

It's nine o'clock on a Saturday. The regular crowd shuffles in.
There's an old man sitting next to me makin' love to his tonic and gin

He says, "Son, can you play me a melody? I'm not really sure how it goes but it's sad and it's sweet
and I knew it complete when I wore a younger man's clothes"

Sing us a song, you're the piano man.
Sing us a song tonight.
Well, we're all in the mood for a melody and you've got us feelin' alright

Now John at the bar is a friend of mine. He gets me my drinks for free
and he's quick with a joke or to light up your smoke but there's some place that he'd rather be

He says, "Bill, I believe this is killing me." as the smile ran away from his face
"Well I'm sure that I could be a movie star if I could get out of this place"

Now Paul is a real estate novelist who never had time for a wife
and he's talkin' with Davy who's still in the navy and probably will be for life

And the waitress is practicing politics as the businessmen slowly get stoned
Yes, they're sharing a drink they call loneliness but it's better than drinkin' alone

Sing us a song, you're the piano man
Sing us a song tonight
Well, we're all in the mood for a melody and you've got us feelin' alright

It's a pretty good crowd for a Saturday and the manager gives me a smile
'Cause he knows that it's me they've been comin' to see to forget about life for a while

And the piano, it sounds like a carnival and the microphone smells like a beer
and they sit at the bar and put bread in my jar and say, "Man, what are you doin' here?"

샤프 전자사전 SD - L530

Misc.2008. 4. 21. 12:35 |


구입: 용산 16만원

너무 익숙해져서, 이거 없으면 어떻게 사나 싶음 ...


There is no tender way to say it's the end
And so win or lose
I am forced to choose
Between a lover and a loving friend
Let me hear you say
How you curse the day


You opened up your heart to me
That you ever invited me in
Tell me I'm the loser and you win

I don't want to see you cry
I beg you try
Not to let the pain I'm causing reach your eyes
I don't want to see you cry
Aim your words like spears
Don't break me up by breaking down in tears

Hide your pain but when push comes to shove
Don't keep your pride
Locked deep inside
Rage against the dying of my love
Don't sigh my name
Give me all the blame
Call me heartless call me cruel
And accuse me of dealing in lies
Just don't let my leaving cloud your eyes

I don't want to see you cry
I beg you try
Not to let the pain I'm causing reach your eyes
I don't want to see you cry
Aim your words like spears
Don't break me up by breaking down in tears
 
Dreams come... dreams go
Some fade... some grow
Dream on, dream on
You've got no dream on
After I've gone

슬픈노래...
미지수 한개인 선형방정식은 ax + b = 0 꼴이다.  머, ax =  b 이렇게 써도 마찬가지다.
이걸 합동식으로 쓰면 ax ≡ b  (mod m )  이다.   이것을 리니어 컨그루언스 라고 한다. ( 언노운은 1개 )

ax = b 는 그냥 양변을 a 로 나누면 되지만,  합동식에서는 나누기가 없다.

우선 곱에 대한 항등원과 역원을 생각해보자. 항등원은 당연히 1 이다. 따라서, 곱해서 나머지가 1 이되는 녀석이 곱에 대한 역원이다.
여기서는, a 의 역원을 a 위에 bar 를 얹어서 나타내기로 하자.

이제,  ax ≡ b  (mod m )    와 같은 합동 방정식이 주어졌다면, 양변에 a 의 역원을 곱하므로써, 좌변엔 x 만 남길수 있고, 따라서 우리는 이 방정식을 푼것이 될 것이다.  그.러.나 !

그것은 때때로 여러개의 해를 갖기도 한다. 그럴땐 위와 같은 방법으로는 고작 하나의 해만 구해진다. 따라서, 위와 같은 방법은 별로 좋은 방법은 아니다. 게다가 역원이 존재하지 않는 경우도 있다.

예를들어, mod 15 에 대한 12 의 역원을 구해보라.   ( 즉 12 에 몇을 곱하면 15 로 나누었을때, 나머지가 1 이 되겠는가? )



자, 이제 다시 처음의 문제로 돌아가서, 언제 해가 구해지는지, 또 유일하게 결정되는지 등을 조사해볼 것이다.
( 이것은 위의 역원에 대한 문제보다 더 포괄적이므로, 역원의 문제를 포함한다. )


선형 합동식의 해에 대한 정리.


존재증명.
( ax - b ) =  m k      for some x , k       즉,  ax - mk  =  b  이고 이것은  디오판투스 방정식이다.
그러므로, 해의 존재는 (a,m) | b 를 나누는가 와 동치이다.    (  참고 : http://sciphy.tistory.com/1304  )
               
해의 개수 증명.
디오판투스 방정식 ax - mk = b 의 주어진 해에 대해,  m / (a,m)  , a / (a,m) 을 더해도 해가 된다. ( 부호가 반대로 둘다 반대로 바꾸면 상관없다.)
우리의 미지수는 x 이므로, m / (a,m) 을 몇번 더하면, mod m 에 대해서 순환하는가를 보면 해의 개수가 나온다.

m / (a,m) 을 (a,m) 번 더하면 결국, m 을 더하게 되므로, mod m 에 대해서 0 을 더하는 것과 같다. 따라서, 해의 개수는 (a,m) 개이다.





위 정리의 결과들.

(a,m) = 1 이면  항상 그리고 유일하게 해가 존재한다.                      1은 b 가 무엇이든 나눌것이고, 해의 개수는 (a,m) = 1 

역원이 존재하려면, (a,m) = 1 이어야 한다.                                      1 을 나눌수있는 수는 1밖에 없으니까...

그러므로, 위에서 구해보라고 했던, mod 15 에 대한 12 의 역원은 존재하지 않는다. ( 서로소가 아니므로... )


행렬을 자주 다루다보면, 왜 굳이 2차원배열만 다루는걸까, 3차원행렬은 없는건가 라는 생각이 들지 않나?

이러한 행렬의 확장된 개념을 Hypermatrix 라고 한다.
사용자 삽입 이미지



케일리도 저런걸 가지고 이렇게 저렇게 해보고 놀았다고 한다.
일반적으로, Rn 에서 Rm 으로의 일반 함수에 대해서, 미분은 Rn 에서 Rm 으로의 선형변환이고, 즉, m x n matrix transformation 이 된다.

차근히, 논리를 전개해보면, 이 행렬의 i번째 행은  f의 i번째 component function 의 미분과 같다는 것을 유도할 수 있다.

사용자 삽입 이미지


그런데 각각의 component function 은 Rn 에서 R 로의 함수이므로, 컴퍼넌트 펑션의 미분은 1 x n 행렬, 즉 row matrix 가 된다.

결과적으로, Rn 에서 Rm 으로의 함수에 대한 미분은, Rn 에서 R 로의 함수에 대한 미분만 구할수 있으면, 각각의 컴포넌트 펑션들을 미분해서 구할 수 있게된다. 그래서, 그것을 각행으로 하는 메이트릭스를 구하면, 그것이 바로 구하고자 하는 미분이 된다.

Rn 에서 R 로의 함수에 대한 미분은 1 x n 매이트릭스고 j번째 열이 f를 j번째 변수로 편미분한 것이 된다.

참고로, 이것은 그레이디언트 오브 f 의  j번째 성분과 같게된다.

따라서, Rn 에서 Rm으로의 함수에 대한 미분은 m x n 행렬이고, 또한, i번째 행은 i번째 성분함수의 그레이디언트의 성분들을 늘어놓으면 되므로, 결국, i,j 성분은 i번째 성분함수를 j번째 변수로 편미분한 것이 된다.

이를 제이코비언(자코비안,야코비안) 메이트릭스라고 한다.

즉, Rn에서 Rm 으로의 함수 f 에 대한 미분은 f의 자코비안 메이트릭스 이다.

다음번엔 다변수 함수의 테일러 전개에 대해 얘기해보자.

Congruence 는 정수의 나머지 연산을 다루기위한 도구로서, 가우스에 의해 disquistiones Arithmeticae 에서 정립되었다.

def. congruence modulo m
a ≡ b (mod m)      denotes        m | (a-b)             ( that is,    a-b = km for some k   )

즉, a 와 b가 나머지연산에 있어 m으로 나누었을때, 같은 나머지(least nonnegative residue)를 갖는 것을 의미한다.

a ≡ b (mod m)  을 간단히 a  ≡m  b 으로 나타내기도 한다.



위의 정의가 같은 나머지를 갖는 두 수를 의미하는지는 다음과 같이 확인해 볼 수 있다.

a = m s + r1  ,   b  =  m t  +  r 2   라고 하면...   a-b  =  m ( s- t) + r1 -  r2   이므로 , m | (a-b) 라는 말은  곧,  m | ( r1 - r2 ) 이 된다.
그런데,   - m  <   r1 - r2   <  m   이므로,    r1 - r2  =  0   밖에 없다.



합동관계 ( congruence relation ) 은 동치관계 ( equivalence relation ) 이다.  ( 참고 :  동치관계  )

pf.
a≡a (mod m)                                                          :    m | 0
a≡b (mod m)  ⇒  b≡a (mod m)                                :    m | (a-b)   ⇒    m | (b-a)
a≡b (mod m)  ∧  b≡c (mod m)  ⇒  a≡c (mod m)     :    a-b = km , b-c = lm  ∴ a-c = (k+l)m    즉, m | (a-c)



기본성질 ( 여기서 modulus 는 m 으로 고정하고 편의상 생략하기로 함. )


1)    a≡b ∧  c≡d      ⇒       a+c ≡ b+d

2)    a≡b ∧  c≡d      ⇒       ac ≡ bd
3)    a≡b                  ⇒       ak ≡ bk   (k∈N)

pf.
1)   a-b = km , c-d = lm    ∴ (a+c)-(b+d) = (k+l)m
2)   a-b = km , c-d = lm    ∴ ac - bc = kcm , bc - bd = blm      ∴ ac - bd = (kc + bl) m
3)   2) 에서 c≡d 대신 a≡b 를 넣고, k 번 적용하면 된다. 인덕션으로 증명.




simple technique
큰수의 나머지 계산에서, 계산과정중에 작은 나머지를 갖는 수를 발견하면, 위의 베이식 프라퍼티들을 이용하여, 언제든지 대체하여 사용할 수 있다.




예제.   2
2008 을 9로 나눈 나머지는?

풀이.   2 3 ≡ -1  이므로,  양변을 제곱하면  2 6 ≡ 1 이다.
          2008 ≡ 208 ≡ 28 ≡ 4 (mod 6) 이므로,    2 2008   =   2 6k + 4   =    ( 2 6 ) 2 4     ≡   16   ≡   7 (mod 9)
          따라서 나머지는 7 이 된다.

디오판투스 방정식은 정수 부정방정식을 말한다.

이 글에서는 2원 1차(linear) 디오판투스 방정식을 다룰 것이다.
즉, a x + by = c  꼴 이다.    ( 당연히, 우리의 관심은 a,b,c 가 0 이 아닐때이다. )

디오판투스의 Arithmetica 는 원래 13권인데, 그중 6권만 전해지고 있는데, 저 방정식의 해법은 없댄다. 대신, 유클리드의 Elements 에 나온다나..

디오판투스 방정식의 해에 존재에 대한 정리.

a x +  b y = c    has a solution if and only if   (a,b) | c

=>  증명)   ax + by = c has a solution, say x0 , y0 , then  ax0 + by0 = c 
                     NOTE.   (a,b) | a , and   (a,b) | b     , therefore ,   (a,b) | c
<=  증명)   (a,b) | c  이면,   c = (a,b) k   ,   NOTE,  (a,b) = ax + by for some x,y
                therefore, c = (ax + by) k = a (xk ) + b (yk)    ,   so, it has a solution (xk, yk )


부정방식은 복수개의 해를 갖을 수 있는데, 주어진 해로 부터, 다른 해를 구하는 방법을 생각해보자.


주어진 해에 대해,      b / (a,b)  ,  -a / (a,b)   를   각각 더해도 해가 된다.


증명.    a ( b / (a,b) ) + b ( -a / (a,b) ) = 0   이므로 주어진 x,y 해에 대해, 더해도, 주어진 방정식에 해를 끼치지 않는다.






예.  7x  +  4y  =  100
      (7,4) = 1  , 1 | 100 ,   따라서 해는 존재함.
      
              x = 4 ,  y = 18    은  해 이므로,       여기에    4, -7 을 임의로 더해도 해가 된다.
따라서,    x= 8  ,  y = 11  도 해이고,
              x=12 ,  y = 4   도 해이고,
              x=16  ,  y = -3  도 해이고, 등등...



이 글은 '최대공약수(gcd) 와 선형조합(linear combination) 1부' 의 내용을 토대로, 몇 가지 자잘한 내용들을 살펴본다.



a 와 b 가 서로소이고,  둘다 c 를 나누면,  ab 도 c 를 나눈다.

증명)  c = a k  = b t   ,   a x + b y = 1        ∴   c = a k  ( a x +  b y )  =  a k ( a x )  +  ab ( ky )  =   b t  ( a x ) +  a b ( ky )  =   ab  ( tx + ky )




다음은 Euclid's lemma. 로 알려져 있다.

a | bc 이고, a 와 b 가 서로소 이면,  a | c

 증명)  bc = ak  ,  ax + by = 1         ∴   acx + bcy = c     ∴  acx + aky = c     ∴  a ( cx + ky ) =   c



공약수를 d ,  공배수를 m , 최대공약수를 g, 최소공배수를   이라 하면, 다음이 성립한다.

d  |  g  |  ℓ  |  m

증명)  1부에서 이미,  공약수가 공배수를 나눈다는 것을 보임으로써, 최대공약수가 최소공배수를 당연히 나눔을 보였었다.
          또한, 1부에서, d | g 를 보였으므로,    |  m 을 보이는 것만 남았다.

          a 와 b 의 공배수와 최소공배수를  m 과    로 놓고, m 을   로 나누는 디비전 알고리듬을 생각하자.
           m   =     q +   r    (    0  ≤   r    <   )

         그러면, a와 b 가 m 과  ℓ 을 나누므로, 따라서, r 도 나누어야 한다. 즉, r 은 a 와 b 의 공배수가 된다.
         그런데 범위가 ℓ 보다 작기 때문에, ℓ 이 최소공배수 라는 것으로 부터, r 은 0 이 된다. 이것으로 증명이 완료된다.




a b = ℓ g

 증명)   a = g k   ,   b  =   g k '    이라고 놓으면,    ab / g   =    ak'  =  bk    이므로,   따라서 a 와 b 의 공배수이다.

임의의 (양의) 공배수를 m 이라고 놓으면,  m /  (  ab /g )  =  mg  / ab   =   m ( ax + by )  / ab   =   (m/b) x + ( m/a ) y  가 된다.
그런데, m 이 a 와 b 의 공배수 이므로  (m/b) x + ( m/a ) y  는 정수이다.

따라서, m / (ab/g) 도 정수이다.  즉, ab/g 는  m 을 나누고, 따라서, ab/g   ≤  m  이다.
공배수 ab/g 는 임의의 공배수 m 보다 작거나 같으므로,  최소공배수이다.   그러므로, ab / g =    이 된다.  


곧바로, 다음의 코롤레리가 얻어진다.

a 와 b 가 서로소 이면,  ℓ = ab 이다.




다음의 것도 자주 사용된다.

a = g s , b = g t   이면, s 와 t 는 서로소 이다.

 사실 이건 1부에서 이미 증명한것이다.  a x + b y = g  에서 양변을 g 로 나누면   (a/g) x + (b/g ) y = 1 로 (a/g) 와 (b/g) 가 서로소.




여기서 부터는,   gcd ( ,  )  , lcm( , ) 보다 더 간단한 표현으로 ( , ) , [ , ] 을 쓰기로 한다.
그러면, "a와 b는 서로소 이다" 는  간단히  (a,b) = 1 로 쓰면 된다.


( a,b )  |  ( ac , bd )

증명)  (a,b) | a | ac ,  (a,b) | b | bd     그러므로, (a,b) 은 ac 와 bd 의 공약수이다. 그러므로 (ac,bd) 를 나눈다.




(ka,kb) =  |k| (a,b)

증명) (ka,kb) = positive min{ kax + kby } = |k| positive min{ ax + by }   증명끝.




다음은 정리는 매우 중요하다.

(ab,cd) = 1   ⇔  (a,c) = (a,d) = (b,c) = (b,d) = 1

증명) 왼쪽에서 오른쪽으로 의 증명은 abx + cdy = 1  부터 자명하므로, 오른쪽에서 왼쪽으로 증명만 남는다.

이것은  (a,c) = (b,c) = 1  ⇒  (ab,c) = 1 임을 증명하면 충분하다.
왜냐면, c 대신 cd 로 치환하면,  연쇄적으로 적용돼서 원하는 증명이 되기 때문이다.

따라서,  (a,c) = (b,c) = 1  ⇒  (ab,c) = 1  만 증명하면...
ax+cy = 1 , bu + cv = 1 이고, 두식을 곱하면,  ab (xu ) + c ( buy + axv + cyv ) = 1 이므로, 증명이 끝난다.



위의 정리로 부터 다음의 정리는 간단히 증명된다.

(a,b)=1,  c|a   이면 ,   (c,b)=1

증명)  ( a,b ) = 1   이고  c | a    ⇒   ( ck , b ) = 1   ⇒   (c,b) = (k,b) = 1   증명끝.






(a,b)=1  이면   (ac,b) = (c,b)

증명)  우선 (c,b) | (ac,b) 는 당연하므로, (ac,b) | (c,b) 임을 보이면 충분하다.
         ax + by = 1  ⇒  acx + bcy = c   , 여기서  (ac,b) 가 ac 와 b 를 나누므로 , 우변의 c 도 나눈다. 증명끝.




(a,b) = 1    이면    ( a , b+ka ) =1

증명)  ax + by = 1   ⇒    ax - kay + kay + by = 1   ⇒   a ( x - ky )  +  (b + ka ) y = 1 




(a,b) = 1  이고   d | ac  ∧  d | bc    이면    d | c

증명) ac = ds , bc = dt , ax + by  =  1  ⇒   acx + bcy = c  ⇒   dsx + dty = c   ⇒   d ( sx + ty ) = c





(a,b) = 1   이면    ( an , bn ) = 1

증명)  ( a2 , b ) = 1  을 보이면 충분, 연쇄적으로 적용하면 되니까.
         ax + by = 1  ⇒  ( ax + by ) 2   =   1    ⇒    a2 ( v ) + b ( 2 axy + by2 )  =  1



마지막으로,  퀴즈  "서로소와 최대공약수" 의 예시답안을 첨부하며 끝을 맺는다.

(a+b,a-b) |  (a+b) ± (a-b)      ∴   (a+b,a-b) | 2a   ,   (a+b,a-b) | 2b    ∴  (a+b,a-b) | (2a,2b)   ∴ (a+b,a-b) | 2 (a,b)   ∴  (a+b,a-b) | 2
  ∴  (a+b,a-b)  =  1  또는  2
            



마음이 편해지는 법

Misc.2008. 4. 17. 03:12 |
내일 1시에 복소 시험인데,  아침 1교시부터 오전 내내 수업이다. 정리는 커녕 책도 다 못봤는데, 이제 숙제 끝내고... 어제도 역학숙제한다고 늦게까지 못자고...

게다가 토요일은 또 다변수 시험인데... 내일 다변수 수업빠질수도 없고... 결과적으로 복소시험까지 공부할 시간이 거의 없다.

가슴이 좀 답답했다. 복소숙제 끝내고, 이제서야 복소 프린트 뽑을려고 eTL 에 들어갔는데, OTL 로 보이는구나.

이런저런 생각이 맴돌다가... 갑자기 마음이 편해졌다. 애초에 시험잘볼려고 용쓴적도 없고, 졸업할때까지 배울수 있는 만큼 최대한 배워가자는게 처음의 마음가짐 아니었던가. 항상 초심을 잃지 말자.

주어진 상황에서 이정도면 내딴엔 최선을 다한거다. 내가 뭐 놀기를 했나, 그렇다고 수업을 빼먹길했나, 잠을 퍼잤나. 그래, 난 할만큼 한거다. 상황이 이렇다면, 어쩔수 없는거다. 이럴때도 있고, 저럴때도 있는거다. 살다보면 누구나 벼라별 사정이 있게 마련이다. 좋을때도 있고, 안좋을때도 있다. 항상 최상의 컨디션과 상황이 주어질순 없다.

진인사 대천명... 진인사에서 조금 뜨끔하지만, 그래도 대천명은 하는거다.

두 수의 최대공약수와 두수의 선형조합 사이의 밀접한 연관은 상당한 충격이었다. 단순한 직관만으로는 그 관계를 짐작하는 것이 쉽지 않기 때문이다. 기껏 떠올릴수 있는거라곤 gcd가 두수의 모든 선형조합을 나눌것이라는 것 정도???

아무튼, 최대공약수와 선형조합 사이의 관계는 정수론 뿐만 아니라, 집합론, 대수학 따위에서도 심심찮게 볼 수 있다는 것 만으로도, 중요성은 재삼 강조하지 않아도 될 것 같다.

그것은 다음과 같다.



두 수의 선형조합들 중에서 양의 최소값은 두수의 최대공약수 이다.




증명.

a 와 b 의 선형조합중에서 양수인것들의 집합을 S 라고 하면, S = { ax + by > 0 | x , y ∈ Z } 이고 , 웰 오더링 프라퍼티에 의해 최소원소가 존재한다.


최소원소를 d = a x0 + b y0   라고 놓으면, 이제 우리가 보일것은 다음과 같다.


1)  d 가 a 와 b 의 공약수 이며...

2)  d 가 모든 공약수 중에 제일 크다.


세부 증명.

1)  a 를 d 로 나누는 디비전 알고리듬을 생각하면...         a = d q + r  (  0 <=   r  < d )


     r 에 대해서 정리하면...

     r =  a - dq =  a -  (a x0  +  b y0 ) q  

       =  a ( 1  - q x0 ) +  b ( - q  y0 ) 


   그러므로,  r 이  0 보다 크다면  S 의 원소가 된다.


그런데,  r 의 범위가   (  0 <=   r  < d )    이므로,  

r 이 S 에 들어가게 된다면, d 가 최소라는 가정에 모순된다.  즉, r 은 0 이라는 말.


   따라서, d 는 a 를 나눈다.   마찬가지로, b 도 나누게 되고.. 따라서, d 는  a 와 b 의  공약수이다.


2)  a, b  의 임의의 양의 공약수를 c 라고 하면,   c  는 a 도 나누고, b 도 나누기 때문에, 그것의 선형조합도 나누게 되고 따라서 d 도 나눈다.

     다시 말해, a  와 b 의 모든 양의 공약수는  d 를 나눈다.   즉, d 보다 작거나 같다. 


1) , 2) 에 의해 증명이 끝난다.





곧바로 다음을 확인할 수 있다.


모든 공약수는 최대공약수의 약수이다.


위 증명의 2) 로 부터 자명하지만, 굳이 명시적으로 다시 증명해보면 다음과 같이 할 수 있다.
c 가 a 와 b 의 공약수라고 하면, a = ck , b = ct   이고,  그러면   g = a x + b y =  ckx + cty =  c ( kx + ty )   이 된다.



게다가 ...


두수의 선형조합의 집합은  gcd 의 배수들의 집합과 같다.


pf)
a와 b의 최대공약수를 (a,b) 라고 하면,        (a,b) | a x + b y      이므로         ax + by = (a,b) k   for some k    이 되니까.


따라서....


 두수가 서로소이면, 두수의 선형조합은 모든 정수를 생성한다.

왜냐면 1의 배수 집합이 되니까.



결과적으로, 다음의 중요한 사실을 알수 있다.


 두수의 선형조합이 1 인 경우를 찾기만 하면, 두수가 서로소임을 보장한다. (역은 당연)


왜냐면, 선형조합 중 양수만 모아놓으면, 그것들중 최소값이 gcd 인데, 1이 있기만 하다면, 이미 최소이므로 자동으로 gcd 가 된다. 즉, 서로소.


예)  연속하는 두 정수는 서로소이다.   증명:  a - b = 1  증명끝.


따라서...

 두수를 최대공약수로 나누면, 서로소이다.


증명은  a x0 + b y0 = (a,b) 에서, 양변을 (a,b) 로 나누면  a/ (a,b) 와 b/ (a,b) 가 서로소임을 알 수 있다.


마찬가지로, 


ax + by = (a,b)  이면,  x 와 y 는 서로소이다.


역시, (a,b) 로 그냥 양변을 나누면 된다.



또다른 이야기로...


어떤 두 수의 선형조합이면서 동시에 공약수이면, 최대공약수이다.



왜냐면, 선형조합이면 최대공약수의 배수이고 ( 즉, 최대공약수 보다 크거나 같다. ) 또한 공약수이므로 ( 즉, 최대공약수 보다 작거나 같다. ) 결과적으로 최대공약수가 된다.


이밖에도 많은 유용한 결과들이 유도된다. 나머지는 다음에 살펴보도록 한다.

이 글은, 앞으로 정수론 관련 글을 쓰기 위한 용어 및 기호의 도입 페이지이다.


정수론의 불문율 : 정수론에서 등장하는 문자들은 특별한 언급이 없을땐 일단 정수라고 가정한다.



1. 정수의 나눗셈

임의의 두 정수 a , b (≠0 ) 에 대하여 ,       a =  b q +  r      (  0  ≤  r  <  |b|  )      으로 표현할수 있는 유일한 q 와 r 이 존재한다.


이때, b 를 제수 ( 읽기는 젯수라고 읽음, divider ) ,   a 를 피제수 ( 피젯수라고 읽음,  dividend )  ,
 q 를 ( quotient ) , r 을 나머지 ( remainder ) 라고 한다.

주의할 것은, 우리의 수학에서는 0 으로 나누는 것을 엄격히 금지하기 때문에, 나누는수, 즉 제수는 항상 0 이 아니어야 한다.
( 즉, 위식에서 b ≠ 0 ) 앞으로는 언급이 없더라도, 0 으로 나누는 것은 자동 배제시키기로 한다.


예)   17 을 -3 로 나누면,    17 = (-3) * (-5) + 2      이므로,   몫은 -5   이고,   나머지는 2 가 된다.




2. 나누어떨어짐 ( divisibility  ) 

정수의 나눗셈에서, 나머지(remainder) 가 0 인 경우,  "나누어 떨어진다" 고 말한다.

나누어떨어짐 (디비저빌러리 -_-  ) 에 대해,  다음의 기호를 도입하자.

a | b      " a divides b "    " a 는 b 를 나눈다. "       ⇔(def )          b = a k    for some integer k 

(  
나누지 않는다는 | 에다가 사선으로 짝대기를 찍 긋기로 한다. )


다시한번 0 으로 나누는 것에 대한 주의를 환기시키자면, 이 경우 a 가 b 를 나누었으므로,
별 말이 없더라도, a 는 0 이 아니라는 말을 포함한다.


디비저빌러리는 다음의 성질이 있다.

 " a | b   ∧    b | c    ⇒   a | c   "         증명:   b = a k , c = b t =  a ( kt )

이런걸, transitive 하다고 한다.   즉, " 디비저빌러리 릴레이션은 트랜지티브 하다. "




3. 약수(divisor) 와 배수(multiple)

a | b   일때,   a 를 b 의 약수,   b 를 a 의 배수 라고 한다.



예)    3 | 0    이므로  3 은 0 의 약수, 0 은 3 의 배수        (   왜냐면,    0  =  3 * 0     ,  몫은 0 , 나머지는 0  )
        0 | 3    은 생각할 수 없다 -_-



4. 공약수 ( common divisor ) 와 공배수 ( common multiple )


d | a1    ∧    d | a2    ∧   ...  ∧    d | an   일 때,    d  를  a1 , a2 , ... , an  의 공약수라고 부른다.

a
| m   ∧    a2 | m    ∧   ...  ∧   an | m   일 때,    m 을  a1 , a2 , ... , an  의 공배수라고 부른다. 



양의 공약수와 음의 공약수가 있는데, 음의 공약수가 단지 양의 공약수에 - 만 붙인거라서, 별 관심을 불러일으키지 않는 관계로, 
보통 공약수라고 하면, ( 혼동의 여지가 없는 경우 ) 양의 공약수를 의미한다.

공배수도 마찬가지다.


divisibility 가 transitive 하므로, 공약수, 공배수의 정의로 부터, 공약수는 공배수를 나눈다.
즉, d | a , ...   이고,  a | m ....  이므로,      d  |   a   |   m    이 되어,     d | m  이 당연하게 성립한다.



5. 최대공약수 ( the greatest common divisor ) 와 최소공배수 (the least common multiple )

공약수 중에서 가장 큰 것을 최대공약수라고 하고,  (양의) 공배수 중에 가장 작은 것을 최소공배수라고 한다.


약칭으로, gcd 와 lcm 이라는 표현을 많이 쓴다.  간혹, 답안쓰다가 실수로 lcd 라고 쓰는 사람들이 있다 ㅋㅋㅋ 나도 ㅋㅋㅋ


표기법으로 다음의 것이 자주 사용된다.

gcd ( 
a1 , a2 , ... , an
 )  :    
a1 , a2 , ... , an
 의 최대공약수
lcm ( 
a1 , a2 , ... , an
 )  :    
a1 , a2 , ... , an
 의 최소공배수

혼동의 여지가 없는 한, 우리는 더 간단히 , 종 종  g  와   혹은  ( ) 와 [ ]  따위로 표현하기도 한다.

예. ( 6 , 8 , 12 )  = 6 , 8 , 12  의 최대공약수
     [ 6, 8,  12 ]  =  6, 8 , 12 의 최소공배수


어찌되었건 최대공약수도 공약수이고, 최소공배수도 공배수이므로,  공약수는 공배수를 나누니까, 따라서, 최대공약수도 최소공배수를 나눈다.


6. 소수 (prime number)

 양의 약수가 2개 인 자연수소수 라고 부른다.

( 소수라고 쓰고, 솟수 라고 읽는다. )



7. 서로소 (relative prime)

 a1 , a2 , ... , an
 에 대해,  임의의 서로다른 두 수 ai , aj 를 골라도, GCD(ai, aj) = 1 일 때, 
 a1 , a2 , ... , an
 를 서로 소 라고 한다.


( 즉, 1 말고는 공약수가 없는 경우이다. )




몇백억 주고 러시아우주선 탑승객으로 간게 무슨 큰 의미가 있는지는 잘 모르겠다. NASA도 우주인으로 인정하지 않는 분위기고... 뭐 사실 맞는말이지. 아마 조종사가 "아무것도 건들지 말아요" 라고 했을지도 모르지.

서럽지만 뭐 ... 처음이니까... 처음은 항상 어려운 법이지...

뭐 어깨너머로 좀 배워오는게 있겠지... 뭐 암튼 그래도 신기하네.

사용자 삽입 이미지

시속 2만7천7백 키로...
초당 대략 8 km 씩 날라가는구나. 빠르다 ㅋㅋㅋ
사용자 삽입 이미지
이안에 그사람이 타고있다 이거지 o_O?


사용자 삽입 이미지

말로만 듣던 허블망원경이 저깄구나..



사용자 삽입 이미지

아리랑 2호 찾았다 !!!!!!

http://spaceflight.nasa.gov/realdata/tracking
http://science.nasa.gov/realtime/

          



백만번 들어도 질리지가 않다. 캐나다의 보배. 애슬린 데비슨...
아래곡들은 내가 뽑은 오래된 버전의 베스트 -_-  ( 렉시코그래피컬 오더임 -_-;;; )




Aselin Debison - Bigger Than Me


Aselin Debison - Carry On

Aselin Debison - Cat In The Sun

Aselin Debison - Driftwood

Aselin Debison - Faze

Aselin Debison - Getting Dark Again

Aselin Debison - Had To Grow Up

Aselin Debison - Lazy Days

Aselin Debison - Life

Aselin Debison - Love Is So Rare

Aselin Debison - Miss you

Aselin Debison - Moonlight shadow

Aselin Debison - Most Of All

Aselin Debison - Once in Every Life

Aselin Debison - Out of the Woods

Aselin Debison - Over the Rainbow-What a Wonderful World

Aselin Debison - Santa Claus Is Comming To Town

Aselin Debison - Some Days

Aselin Debison - Stupid Things

Aselin Debison - Sweet Is the Melody

Aselin Debison - Thank You (For Breaking My Heart)

Aselin Debison - The Dance You Choose

Aselin Debison - The Friend In Me

Aselin Debison - The Gift

Aselin Debison - The Island

Aselin Debison - To Say Goodbye To You

Aselin Debison -Rise Again



애슬린 데비슨 베스트 전체듣기.

헤더파일들이 함수정의와 같은 이름의 매크로 정의도 가지고 있는 경우가 많다.

가령, cype.h 에는 isalpha() 가 매크로로 뿐만 아니라 함수로도 정의가 되어있다.


isalpha() 의 함수버전을 쓰고 싶다면, 

당연한 얘기지만, #undef 로 매크로를 취소해버리면 되기는 한다.


#undef isalpha


그러면, isalpha() 는 자동으로 함수가 되는데, 그럼 그 다음의 어딘가에서 macro version 을 코드에서 사용하는 것이 어려워진다.


이럴때, 괄호 ( ) 를 이용해서, 매크로를 undef 하지 않고도, 함수를 선택할 수 있다.


식별자를 ()로 감싸버리면, 매크로의 형태와 달라지기 때문에, 해당매크로로 인식을 하지 않고 따라서 치환하지 않는다. 반면, 함수의 경우, 식별자를 괄호로 감싸도 여전히 호출하므로 함수버전을 호출할 수 있게 된다. 


가령, 위의 isalpha() 를 예로 들면, (isalpha)() 로 사용하는 것이다.


예.

#include<stdio.h>


void prn_int(int j){

printf("%d\n" , j );

}


#define prn_int(i) printf( #i " = %d\n" , i )


int main(int argc, const char * argv[]) {

int a=10;

(prn_int)(a);

prn_int(a);

return 0;

}


결과.

10

a=10 


NOTE.

위 예제에서, #define 부분을 prn_int() 함수 정의 앞으로 옮기게 되면, error. 왜냐면, 함수 정의 부분에서 함수 이름을 replace 해버림.


3차원 일반회전행렬

Math2008. 4. 10. 08:29 |
사용자 삽입 이미지

잘 보면 규칙이 있다. 


위 행렬을 구하는 방법은 매우 다양하다.

특히, 회전행렬을 몰라도, 초등 벡터기하 만으로도 유도가 가능하다.
내적하고 외적을 적절히 조합하니까 생각보다 금방 구해진다.

ANSI C 에는 미리 정의된 5개의 매크로가 있고, 항상 사용가능하며, #undef 가 안된다.

__DATE__   :  매크로가 치환되는 순간의 날짜 (문자열)
__TIME__   :  매크로가 치환되는 순간의 시간 (문자열)

__FILE__    :  매크로가 치환되는 순간의 소스파일의 경로와 이름 (문자열)

__LINE__    :  매크로가 치환되는 순간, 매크로의 LINE 번호 (정수형)
                   빈줄도 센다. 즉 코드 레벨에서 세는것이므로, 의미따윈 두지않고 빈라인이건 뭐건 그냥 카운팅한다.

__STDC__  :  Standard C 를 comply 하는가. (1 or 0)

(단, VC++ 쓰는 경우는 디폴트가 C++ 이라, __STDC__ 가 정의되어있지 않다. 즉, 그냥 변수로 인식하는데, 앞에서 선언을 해주지 않으면 오류가 난다.)

예.
#include<stdio.h>
#include<conio.h>

int main(void){
    printf("%s\n%s\n%s\n%d\n",__DATE__,__TIME__,__FILE__,__LINE__);
    getch();
    return 0;
}

실행결과는 다음과 같다.

Aug 19 2008
07:21:14
D:\C Language\test.c
5


도그 1집 전곡

Misc.2008. 4. 9. 14:11 |
사용자 삽입 이미지
고3때 박봉신 때문에 알게된 도그 1집. 나는 도그 1집을 주저없이 국내 명반리스트에 넣는다. 표지에 보이는 여자가 왁스다. 왁스가 나왔을때, 왁스가 도그녀인줄 모르고, 거참 목소리 똑같네 했었다. 알고보니 왁스가 도그녀더라.

나는 도그녀가 여성이면서도 롹보컬이라서 참 좋아했다. 당시엔 여성과 롹사이에는 인터섹션이 크지 않았던게 사실이다. (지금도 마찬가진가?) 나는 당시 "음악은 역시 롹이지" 라고 믿는 롹키드였었고, 친구들끼리도 SES나 핑쿨을 들으면 음악을 모르는 녀석이고, "롹을 들어야 음악을 아는 녀석"이라고 말하던 시기이다.

나는 도그녀가 진정한 음악은 롹이라고 생각하는 롹숭배주의자 여성이라고 믿었고, 그래서 많이 좋아했다. 아 이런 여자를 만나야 해... 라면서... 박봉신은 진짜로 그녀의 외모까지도 좋아했던것 같다. 그러다가 나중에 도그녀가 왁스를 바르고 나와서는, 오빠오빠~하고 노래를 부를때 적잖이 실망했던 기억이 난다. 롹을 버리다니...라고 생각했다. 하지만, 도그녀로서는 생존을 위한 선택이었는지도 모른다.

이에 대한 설명은 시디 속지로 충분하다. 시디 안쪽을 보면, 도그의 다름 멤버 사진들이 나온다. 보는 순간 아...씨... 이건 뭐야 ... 라는 감탄사(-_-;;)가 나온다. 여성팬이 전무했던것으로 안다. 밴드가 생명을 유지하기 위해 팬은 반드시 필요하다. 팬이 음악만으로 확보되지 않은 것이 참 서글프지만 그게 현실인가보다. 홍보를 안한것도 아니다. 방송출연도 했고, 음반사도 빵빵했고, 저녁시간대에는 라디오에서 앨범 광고도 했지만... 도그남들의 마스크는 모든걸 무색하게 만들었다. 수만횽은 그래서 그렇게 애들을 성형시키나보다.

그렇다고 도그1집이 완전히 망한건 아니었다. 특이한 스타일의 "경아의 하루"가 꽤 알려졌고, "집에돌아오면"도 꽤 뜨긴 떴었다. 근데, 시디를 들어보면 전곡이 골고루 좋다. 들어보자 !!!


- 전곡 듣기 !!!

1번 트랙. 나의 10대.
학교도 안좋아했고, 공부도 열심히 안하고 매일 혼나는... 아주 평범한(?) 10대였단다.
10대의 추억이 모두 엉망이지만 그래도 지금보다는 낫단다.

2번 트랙. 첫사랑. (외국곡)
술에취해 그렇게 됐단다. 친구보단 내가 더 중요했단다.
넌 언젠간 떠나겠지 그녀를 떠나듯이, 너에겐 정말 미안하다고...
그래도 좋은걸 어쩌냐는...

3번 트랙. 조금만 기다려.
조금만 기다려 모두다 말하려하지마.
너 세상을 다 가질듯 미쳐있지만.
며칠만 기다려 너는 놀라게 될거야
점점 너의 변하가는 가벼운 입술에
내게 다가오지마 일생의 동반자처럼....

4번 트랙. 경아의 하루.
골때림. 당시에 이미 된장녀에대한 설캐즘을 보여준 노래.

5번 트랙. 집에 돌아오면.
차트에 좀 올라갔던 노래. 모두가 널 그리고 있으니 집에 들어오라는 ;;;
호소력 짙은 목소리가 왁스 그대로임.

6번 트랙. 질 나쁜 소녀.
머리색이 이상하면 문제가 없어도 소곤소곤 나는 질나쁜소녀라는...
그냥 평범한게 싫어서 그러는거니까 피해안줄테니 좀 내버려두라는..

7번 트랙. 강해져야 해.
너를 떠나기가 너무 싫지만
강해져야해.

8번 트랙. 다롱이.
강아지 다롱이. 사랑한다는...

9번 트랙. 나는 그를 알아요.
그는 거짓덩어리

10번 트랙. 오빠.
 차라리 덜 좋아해줘... -_-;;
 

컴파일 전에 코드 수준에서의 조작에 있서서도 조건부 조작이 가능하다.

#if
바로 뒤에 상수 또는 이미 정의된 문자상수가 온다. 즉, 평가시 상수인 표현이 온다.
평가값이 0 이면 다음줄 부터의 내용을 건너뛰고, 평가값이 0이 아니면 처리한다.

#ifdef
#if 와 마찬가지인데, 단지 바로 뒤에 나오는 식별자가 #define 으로 미리 정의가 되어있으면 처리 하고, 그렇지 않으면 건너뛴다.

#if defined
#if defined 에서 defined 는 뒤따라 오는 식별자가 정의되어있으면 1을, 그렇지 않으면 0 으로 평가된다.

defined 는 여러개 사용될수 있으며 논리부정도 가능하다.

#if defined(identifier) 는 #if defined identifier 와 같다.

예. #if defined(HP9000) || defined(SUN4) && !defined(VAX)

가령 VS2008 에서 math.h 를 열어보면, 수학상수 쪽 코드를 보면,
#if defined(_USE_MATH_DEFINES) 뭐 요딴게 들어있는데, 따라서, 수학상수 가령 M_PI 같은 거 쓰려면
앞부분에 #define _USE_MATH_DEFINES 하고 정의해줘야한다.


#ifndef 는 if not defined 이다. 논리부정만 빼면 #if와 같다.

이것은 다음과 같은 형태로도 자주 쓰인다.

#ifndef ABC
#define ABC 123
#endif


즉, 정의되어있지 않다면, 이렇게 정의해라 라고 명령한다.



#else , #elif
전처리기의 조건부 컴파일은, if 문의 else와 유사하게  #else 를 가지고 있고, else if 와 유사하게 #elif 를 가지고 있다. 방식도 유사하다.


#endif
조건부 컴파일의 종료를 나타낸다.


---------------------------------------------------------------------------------------

조건부 컴파일은 코드의 특정부분을 껐다가 켰다가 할 때 사용할 수도 있다.
물론, 많은경우 주석문으로 감싸버리면 특정 코드를 삭제할 수 있지만, 삭제하는 부분에 주석문이 들어가있으면 오류가 날 수도 있다.

가령, /* 와 */ 로 감쌌는데, 감싼 코드에 /* ... */ 들어있으면... 코드부분의 */ 과 반응하여 주석이 닫혀버리기 때문에 이후의 부분은 주석화 되지 않는다.

그럴때, 문제없이 통째로 주석화 시켜버리는 방법은 다음과 같이 감싸는 것이다.

#if 0
...
#endif

감싼 부분을 켰다껐다 하는 것은 #if 의 0 을 1과 바꿔가며 작업하면 된다.



이와 같이 코드의 특정부분을 컴파일 할지 말지 선택할 수 있는데, 이것을 동시에 여러부분에 적용할 수 도 있다.
가령 다음과 같이 하면 된다.

코드 앞부분에 #define DEBUG 1  과 같이 매크로를 하나 정의해놓고,

켰다 껐다 할 코드의 각 부분들을 모두 #if Take  , #endif 로 감싸버린다.
이렇게 하면 #define Take 1 의 상수를 0 또는 1 로 바꿔가면서, 코드의 여러부분을 동시에 컴파일할지 말지 결정할 수 있다.

예.
#define Take 1
...
...

#if Take
...
#endif
...
...
#if Take
...
#endif
...


여기에 하나더 응용해서 #if !(Take) 와 같이 논리부정을 사용하여 반대로 조건부 컴파일 되는 부분을 지정해주면, 상호 배타적으로 컴파일 되는 부분을 만들수도 있다. 물론, 한덩어리의 형태라면 #else를 써도 되고, 다양한 선택사양이 있다면, #elif 를 중복사용해도 된다.

#ifdef 도 마찬가지로 쓸 수 있다. 이때는 앞에 #define DEBUG 만 있으면 되고, 이 매크로를 삭제해버리면 컴파일 안되게 할 수 있다. #ifndef 하고도 잘 섞어서 쓰면 여러가지 기능을 구현할 수 있다.

#error
전처리기가 전처리 지시자 #error 를 만나면, 컴파일 오류를 발생시키며, 지시자 뒤의 문자열을 화면에 출력한다.


예.
#ifndef __STDC__
     #error None Standard C
#endif

#include<stdio.h>

int
main(void) {
     printf("Standard C\n");
     return 0;
}


__STDC__가 정의되어 있지 않은상태에서, 컴파일을 시도하면 다음과 같이 오류메시지가 뜬다.

--------------------Configuration: temp - Win32 Debug--------------------
Compiling...
temp.c
d:\temp\temp.c(2) : fatal error C1189: #error :  ANSI C is not the default.
Error executing cl.exe.

temp.exe - 1 error(s), 0 warning(s)

-----------------------------------------------------------------------------------------------------

#line

The #line directive tells the preprocessor to change the compiler's internally stored line number and filename to a given line number and filename.

#line integral_constant  "filename"

컴파일러로 하여금 다음 행의 행번호를 주어진 번호( 즉, 윗 구문의 integral_constant 정수상수) 로 바꾸게 하고, 파일이름을 주어진 파일명으로 믿게만든다.

여기서 filename 은 옵션이다. (표시하기 귀찮아서 옵션표시생략했다.)

__FILE__ 과 __LINE__ 를 사용하는 코드를 작성후, 해당 코드 이전에 #line 150 "newname.txt" 를 써보면 출력결과가 달라지는 것을 확인할 수 있다.

---------------------------------------------------------------------------------------------------


#pragma 지시자는 나중에 따로 자세히 다루기로 한다.

사용자 삽입 이미지

간: 간단히 말해서
미: 미분가능하면
연: 연속이다.

사용자 삽입 이미지

국내 소설의 주류는 문체의 소설이 되어버린것인가.

지나게 섬세한 장면 묘사. 온갖 의미를 다 담아서... 뭐 그리 의미가 많은지... 후... 난 읽다 지친단말이다.
또한 지나친 묘사는 독자의 상상의 나래를 상당부분 제약한다.

어쩔땐 그런게 plot 의 부재를 몰고오기도 한다. 죄다 1인칭시점에, 끝없는 독백에...좀 지겹지 않은가.
난 좀 지겹다 ;;;

그냥 할머니 무릎베고 누워서 듣던 옛날얘기 같은 그런 소설이 그리울때가 있단말이다. 그냥 누가누가 이랬고, 누구는 저랬단다. 그래서 어쨌고, 그래서 어쨌댄다.

수식도 없고 화려한 문체도 없지만 할머니할아버지의 옛날얘기는 재밌다.

이탈로 칼비노의 [반쪼가리 자작] 은 스토리텔링이다. 그래서 이야기의 전개속도도 거의 할머니할아버지 옛날이야기만큼 빠르다. 암튼 참 재밌고, 생각할것도 던져준다. 게다가 일단 얇다.

타고난 이야기 꾼...이탈로 칼비노.

전처리 연산자 #은 매크로 정의에서 형식 매개변수를 문자열화 한다.

가령 다음과 같이 매개변수를 갖는 매크로를 정의하면,

#define print(a) printf(#a)       //  매개변수로 들어온 녀석을 " 로 감싸버려서 치환해준다.


이제  print(Hello world!\n);   는   printf("Hello world!\n"); 으로 바뀐후 컴파일된다.


몇가지 간단한 응용을 생각해 볼 수 있다.


예1.
#define love(a,b) printf(#a " loves " #b)
이렇게 쓰면, love 가 받는 두개의 인자가 각 각 " " 묶여서 치환되고, printf 내에 " " 세개가 나란히 들어가게 되는데,
나열된 문자열상수는 결합되기 때문에 문자열 a와 b가 포함된 문자열을 인쇄한다.

가령, love(James,Lisa); 라는 코드는, printf("James loves Lisa"); 로 바뀐다.

예2.
#define print(a) printf(#a " = %d\n",a)
이렇게 쓰면, 정수형변수를 받아서, 그것의 이름과 십진정수값을 포함한 문자열을 출력하는 간단한 매크로가 만들어진다.

-------------------------------------------------------------------------------------------

연산자 ## 은 토큰을 결합하는데 사용한다.

가령 x ## i 는 x와 i 라는 두개의 토큰을 하나의 토큰 xi 로 만들어 준다. 이것은, 각각의 토큰 x 와 i 가 파라미터로 쓰이면서 하나의 토큰 xi 를 만들수 있게 해준다.

예. #define U(a,i) a##i    // 코드에서 U(x,1) 라고 썼다면, 그부분을 x1 로 대체한다.
     #define F(i) f##i   


#와 ##을 사용하여, 배열과 인덱스를 파라미터로 받아 출력하는 매크로를 다음과 같이 만들수도 있다.

#define arrprint( arr, index ) printf(#arr "[%d] = %d\n" , index, arr ## [index] )

가령 int a[3]={10,15, 22} ; 라고 있을때,
       arrprint(a,2);   라는 코드는 다음의 코드로 치환된다.

      printf("a" "[%d] = %d\n",2,a[2]);

그런데, 연속된 문자열이 접합되므로,       printf("a[%d] = %d\n",2,a[2]);  이 된다.




[C언어] #define 와 #undef

COM2008. 4. 5. 13:33 |
#define 은 무념무상으로다가 바꿔치기 해주는 역할을 하는데, 이거슨 preprocess(전처리) 과정에서 이루어지므로, 사실상 코드에 직접적으로 손을 대는 것과 같다.

소스를 통해 전반적으로 반복되는 상수나 혹은 수식 따위가 있을때 그것을 다른 식별자로 치환시켜 놓고, 프로그래밍하면, 이후에 그 상수나 수식따위의 변경이 필요할때, #define 에서 한번만 수정해주면, 코드 전체를 통해 일괄적으로 수정한 효과를 보게 되며, 이는, 프로그램의 이식성을 높여준다.

즉, #define 은 매크로정의 전처리기이다.


사용법은 보통 다음과 같은 형태를 갖는다.

#define identifier token_stringopt
#define identifier(identifier, ... , identifier) token_stringopt
                     //파라메터를 갖는 매크로

보다시피 토큰-스트링이 옵션이기 때문에 없어도 된다. 경우에 따라 그것이 정의되었는지 여부만을 따질 때가 있기때문이다.

토큰스트링이 있을 경우, 전처리 과정에서, 명시된 식별자와 이후의 토큰스트링을 같다고 정의한다.
정의가 길어져서 행이 넘어갈땐 backslash 를 사용하여 연장할 수 있다. 매크로정의는 컴파일전에 우선적으로 코드를 치환시킨다.

----------------------------------------------------------------------------------------------------

#define 은 파라메터를 사용하여, 수식따위를 치환해서 쓸때도 유용한데, 이때 주의할것은 전처리기가 무념무상으로 치환하기 때문에, 괄호()를 사용하는 것이 예기치 못한 오류를 막는 좋은 습관이되겠다.

예를들면,    #define sqr(x) x*x         보다는  #define sqr(x) (x)*(x)      로 쓰는것이 좋다.

왜냐면, sqr(a+b) 로 쓸때, 우리가 원하느 것은 (a+b)*(a+b) 인데, 첫번째 방식으로 #define 을 쓸경우, a+b*a+b 가 되어 예상과 다른 결과를 준다.

이때, x는 int니 char 니 하는 거랑은 전혀상관없이, 그냥 컴파일 전에 소스에서 치환하는 인자일뿐이다.


위에서 보듯이, 파라메터를 사용한 매크로는 겉보기와 기능에서 함수와 같은 역할을 수행할 수 있다.
이것은 많은 경우에 매우 권장되는데, 기능은 함수와 같으면서도 제어의 흐름상 함수호출이 없기때문이다.

게다가, 세미콜론 ; 을 사용해서 디파인을 사용하면, 하나의 모듈로서도 써먹을수가 있다.

----------------------------------------------------------------------------------------------------

또한, #define 은 코딩의 구문을 자신의 기호에 맞게 변경하는데도 쓸 수 있다.

예.  #define NOT !=


주의.  #define A B 의 형식에서, A를 B로 대체하는데, 이때, A는 identifier 혹은 그것에 파라메터가 달린 꼴 이므로, identifier 를 만드는 규칙에 따라야 한다. 가령 !나 # 따위의 기호는 사용할 수 없다. 반면 B위치에 들어가는 것은 token_string 이므로, ! 나 = 따위의 연산자나 ; 따위의 펑츄에이션도 가능하다.



#define 은 앞에서 정의된 매크로를 재사용하여 정의할수도 있다.

예.

#define min(x,y) (((x)<(y))?(x):(y))
#define minmin(a,b,c,d) min(min(a,b),min(c,d))


-------------------------------------------------------------------------------------------------


매크로 정의를 해제하는 방법은 #undef 를 쓰면 된다.

#undef identifier

아니, #undef 는 왜 쓸까? 애초에 #define을 안하면 될 것 아닌가... 하지만 그렇지가 않다. 우리가 #include 하는 헤더파일에 대해 모든것을 알고있지 않는한 #undef 는 필요하다. 내가 정의하고픈 매크로가 포함하려는 어떠한 헤더파일에 이미 정의되어 있을 수 있기 때문이다. 표준헤더가 아닌 사용자정의 헤더의 경우에는 특히 더 그렇다.

인자를 갖는 매크로를 해제할때도, 식별자만 써주면 된다.

다음과 같은 형태로 많이 쓴다.

#undef identifier
#define identifier

서브그룹의 인덱스

Math2008. 4. 4. 02:08 |
H ≤ G

Def. Index of H in G.
= the number of left cosets of H in G and denoted by (G : H)
( same as right coset. )

then, since Lagrange's Thm can be rewritten as |G| = |H| (G : H)
the index of H in G can be rewritten as  (G : H) = |G| / |H|

Then, for K ≤ H ≤ G

( G : H ) = |G| / |H|
( H : K ) = |H| / |K|
( G : K ) = |G| / |K|

thus,
( G : K ) = ( G : H ) ( H : K )

Let G be a finte group and a ∈ G.

since <a> is a subgroup of G , so the order of the subgroup must divides the order of G.

that is,  |<a>| | |G|

here, |<a>| = |a| = o(a)   : the order of the element a.

therefore,
the order of every element divides the order of the group.

" Every group of prime order is cyclic."


 Let G be of prime order p , and let a be an element of G other than the identity.

Consider the cyclic subgroup <a>.
Since a ≠ e , |a| = |<a>| ≥ 2 .

By Lagrange's theorem, |<a>| must divide |G| = p

There are only two numbers dividing a prime number, that is 1 and p itself.
Since |<a>| ≠ 1 , |<a>| = p .

Thus G = <a> , so G is cyclic.