https://www.reddit.com/r/factorio/comments/93g03s/simplest_7segment_display_possible_09_displayed/
에서 조합기 2개로 7세그먼트 디스플레이를 만드는 글을 찾았기에 한번 분석해 보기로 하였다.
일반적으로 7세그먼트 디스플레이 청사진을 찾아보면 적게는 4개, 많게는 15개까지 조합기를 쓰는 경우를 볼 수 있는데, 이 경우는 조합기 2개만 써서 흥미로웠다.
청사진을 설치해서 확인해 보니, 산술연산 조합기에서 <<연산을 하고 있는 것을 보았다.
https://wiki.factorio.com/Arithmetic_combinator 에서 찾아보니 이는 '시프트 연산'을 위한 기호라고 한다.
https://www.reddit.com/r/factorio/comments/6706gn/possibilities_with_new_combinator_options/ 에서 산술연산 조합기에 대해 읽을 수 있다.
https://en.wikipedia.org/wiki/Bitwise_operation - 위키백과 비트 연산
https://en.wikipedia.org/wiki/Arithmetic_shift - 위키백과 산술 시프트
https://en.wikipedia.org/wiki/Logical_shift - 위키백과 논리 시프트
팩토리오는 32비트로 정수를 표현하는데, 이는 32개의 0과 1로 정수를 표현한다는 뜻이다.
예를 몇 개 들어보면, (편의를 위해 8자리씩 끊어 표기하였음)
00000000 00000000 00000000 00000001(2) = 1(10)
00000000 00000000 00000000 00001001(2) = 9(10)
00000000 00000000 00000000 10001001(2) = 137(10)
이 된다.
1의 자리, 10의 자리, 100의 자리... 등등이 있는 십진수(10)와는 다르게, 1의 자리, 2의 자리, 4의 자리, 8의 자리... 등등이 있는 이진수(2)를 사용한다.
이진수 101101(2)는 1+0+4+8+0+32이므로 45(10)이다.
그럼 32비트로 음수는 어떻게 표현하는가, 이를 이해하려면 먼저 2의 보수에 대해 알아야 한다.
https://en.wikipedia.org/wiki/Two%27s_complement - 위키백과 2의 보수
2의 보수는 어떤 수를 커다란 2의 거듭제곱에서 빼서 얻은 수이다.(이 경우에 커다란 2의 거듭제곱은 2^32, 4294967296이다.)
일반적으로 2의 보수는 원래 수의 음수 취급된다. 예를 몇 개 들어보자면,
11111111 11111111 11111111 11111111(2) = 4294967295(10)이 되야 할 테지만,
4294967295는 4294967296-1이기 때문에
11111111 11111111 11111111 11111111(2) = -1(10)이 된다.
2의 보수를 쉽게 구하는 방법은 모든 자릿수를 반전시킨 다음 1을 더하는 것이다.
예를 들어 -137(10)을 32비트 정수로 변환하려면,
00000000 00000000 00000000 10001001(2) 의 자릿수를 반전시켜
11111111 11111111 11111111 01110110(2)으로 만들고 1을 더해 11111111 11111111 11111111 01110111(2)으로 만든다.
11111111 11111111 11111111 01110111(2) = 4294967159(10)이 되어야 하지만,
4294967159는 4294967296-137이기 때문에
11111111 11111111 11111111 01110111(2) = -137(10)이 된다.
마지막으로, 10000000 00000000 00000000 00000000(2)는
2147483648(10)도 될 수 있고, -2147483648(10)도 될 수 있을 것으로 보이지만 -2147483648(10)이라고 약속을 해 놓았다.
맨 앞자리가 1일 때 음수, 0일 때 양수라고 생각해도 될 것이다.
이제 시프트 연산에 대해 알아보면, 좌측 시프트 연산(<<)은 모든 자리를 왼쪽으로 한 칸 '밀고', 우측 시프트 연산(>>)은 모든 자리를 오른쪽으로 한 칸 '미는' 연산이다.
예를 들면, 0001(2)에 좌측 시프트 연산 2회를 하면 0100(2) 가 된다.
이제 7세그먼트 장치로 돌아가 보자.
일정신호 조합기에서 지속적으로 신호들이 입력되고 있다.
자세한 수치는 다음과 같다.
(0신호) 1207959553(10) = 01001000 00000000 00000000 00000001(2)
산술연산 조합기는 빨간 선으로 0-9 사이의 숫자 D를 받는다.
D가 0이면 신호가 그대로 나올 것이고, 1이면 모두 1씩 좌측 시프트가 되어 나올 것이다.
조명은 신호가 양수일 때만 켜지도록 되어 있다.
그러므로, 맨 앞자리가 0이면 ON이고 1이면 OFF이다.
다음은 각 조명이 받아들이는 신호값이다. 지급 D값은 0이므로 3신호 빼고 다 켜져 있는 모습을 볼 수 있다.
각 산술연산 조합기에는 신호가 15종류까지 들어가므로, 응용을 하면 다른 폰트는 얼마든지 만들 수 있다.
출처: https://forums.factorio.com/viewtopic.php?f=193&t=19825&sid=1bc80166742c245337c903251d778ff6&start=60#p282391 by Yamanqui
산술연산 조합기를 두세개 사용함으로써 더 복잡하고 정교한 숫자 모양을 만들 수도 있다.
글로만 봐서는 이해가 되지 많을 수도 있으니, 가장 바람직한 것은 물론 청사진을 직접 내려받아 뜯어보고 분석하는 일일 것이다.
청사진: https://pastebin.com/4gGEJTmw
진자 프로그래머 그자체 ㄷㄷ 탁상시계보면서 감탄하는중
한글 디스플레이는요
알파벳이면 모를까 한글은 너무 어렵지
저번 학기에 verilog로 고통받은거 생각나네
설명을 너무 친절하게 잘해주는데 너무 어려워서 이해불가
팩토리오는 그 어느 쪽도 아닌데, 좌측 시프트 연산을 행하면 맨 왼쪽에서 사라진 숫자가 맨 오른쪽에 나타나기 때문이다. <-- 이부분 해보니까 아닌것 같은데
ㅇㅇ 이 글 쓸 당시에 헷갈려서 잘못 적어놓은거 같다 shift n 은 shift (n mod 32)로 취급되는게 맞음
틀린부분 수정하고 가독성 조금 올려놓음