dc(컴퓨터 프로그램)
dc (computer program)원본 작성자 | 로린다 체리, 로버트 모리스 (AT&T 벨 연구소) |
---|---|
개발자 | 다양한 오픈 소스 및 상업용 개발자 |
기록 위치 | B |
운영 체제 | Unix, Unix 유사, Plan 9 |
플랫폼 | 크로스 플랫폼 |
유형 | 명령 |
dc(데스크 계산기)[1]는 임의의 정밀 산수를 지원하는 교차 플랫폼 역폴란드 계산기다.벨 연구소의 로린다 체리와 로버트 모리스가 쓴 이 책은 C 프로그래밍 언어가 발명되기 이전인 유닉스 유틸리티 중 가장 오래된 것이다.[2]그 빈티지의 다른 유틸리티들과 마찬가지로, 그것은 강력한 특징들을 가지고 있지만 구문들을 가지고 있다.[3][4]전통적으로 dc 위에 bc 계산기 프로그램(infix 표기법)이 구현되었다.
이 글은 언어의 일반적인 맛을 보여주려는 시도로 몇 가지 예를 제시한다; 명령과 구문의 전체 목록은 자신의 특정한 구현을 위해 맨 페이지를 참조해야 한다.
역사
dc는 살아남은 유닉스 언어 프로그램 중 가장 오래된 프로그램이다.그것의 집 Bell Labs가 PDP-11을 받았을 때, Dc는 조립자 이전에도 새로운 컴퓨터에서 처음으로 실행된 언어였다.[2]Ken Thompson은 dc가 기계에 쓰여진 최초의 프로그램이라고 생각해왔다.[5]
기본 연산
4와 5를 dc로 곱하려면(대부분의 공백은 선택 사항임)
$cat << EOF > cal.Txt 4 5 * p EOF $ dc cal.txt 20 달러
결과는 다음 명령에서도 확인할 수 있다.
$ 에코 "4 5 * p" dc
또는
$dc - 4 5*pq 20$ dc 4 5 * p 20 q $ dc -e '4 5 * p'
이것은 "4번과 5번을 스택에 밀어넣은 다음, 곱셈 연산자로 스택에서 두 개의 원소를 터뜨려 곱하고 그 결과를 스택에 밀어 넣는다"로 해석된다.그러면.p
명령은 스택의 상단 요소를 검사(화면으로 인쇄)하는 데 사용된다.그q
명령어는 호출된 dc 인스턴스를 종료한다.일부 연산자는 그럴 필요가 없더라도 숫자는 서로 간격을 두어야 한다는 점에 유의하십시오.
명령어를 사용하여 산술 정밀도가 변경됨k
산술 연산에 사용할 분수 자릿수(점 뒤에 오는 자릿수)를 설정한다.기본 정밀도는 0이므로 이 명령 시퀀스는0
그 결과:
2 3/p
정밀도를 조절하여k
임의의 소수 자릿수를 생성할 수 있다.이 명령 시퀀스 출력.66666
.
5 k 2 3 / p
+ (-) 4) \ : (v
스택 상단의 제곱근을 계산한다._
음수를 입력하는 데 사용됨:
12 _3 4 ^ + 11 / v 22 - p
스택의 상위 두 요소를 바꾸려면r
명령하다상단 요소를 복제하려면d
명령하다
입출력
stdin에서 한 줄을 읽으려면?
명령하다이것은 마치 dc 명령어인 것처럼 선을 평가하기 때문에, 구문적으로 정확할 필요가 있고, 그 때문에 잠재적인 보안 문제를 제시할 필요가 있다.!
dc 명령은 임의 명령 실행을 활성화한다.
위에서 언급한 바와 같이p
스택의 맨 윗부분을 그 뒤에 새 줄로 인쇄한다. n
스택의 상단을 툭툭 쳐서 후행 뉴라인 없이 인쇄한다. f
한 줄에 한 항목씩 전체 스택을 인쇄하십시오.
dc는 임의의 입력 및 출력 라디스를 지원하기도 한다.그i
명령어는 스택의 상단을 팝업하여 입력 베이스에 사용한다.16진수는 dc 명령과의 충돌을 방지하기 위해 대문자여야 하며 A-F로 제한된다.그o
명령어는 출력 베이스에 대해 동일한 작업을 수행하지만, 입력 베이스는 이후 모든 숫자 값의 구문 분석에 영향을 미치기 때문에 일반적으로 출력 베이스를 먼저 설정하는 것이 바람직하다.그러므로10o
출력 라디스를 전류 입력 라디스로 설정하지만 일반적으로 10(10)으로 설정하지 않는다.그럼에도 불구하고Ao
출력 베이스를 입력 베이스와 관계없이 10으로 재설정한다.값을 읽으려면K
,I
그리고O
명령어는 현재 정밀도, 입력 라디스와 출력 라디스를 스택의 상단으로 밀어 넣는다.
예를 들어, 16진수에서 2진수로 변환하려면:
$ 에코 16i2o DEADBEEP dc 110111101011011101110111011101110111011101110111011111111111111111111111111
언어 기능
레지스터
dc는 이러한 기본적인 산술 연산 및 스택 연산 외에도 매크로, 조건화 및 이후 검색을 위한 결과 저장에 대한 지원을 포함한다.
매크로와 조건의 기초가 되는 메커니즘은 레지스터로, dc에서는 다음과 같이 저장 및 검색할 수 있는 단일 문자 이름을 가진 저장 위치다.sc
스택의 상단을 펑하고 레지스터 c에 저장한 후lc
레지스터 c 값을 스택에 밀어 넣는다.예를 들면 다음과 같다.
3 Sc 4 lc * p
레지스터도 2차 스택으로 취급할 수 있으므로 값을 사용하여 레지스터와 메인 스택 사이에 밀어넣고 튀길 수 있다.S
그리고L
명령어
줄들
문자열 값은 다음 위치에 포함됨[
그리고]
문자를 스택에 밀어넣고 레지스터에 저장할 수 있다.그a
명령은 숫자 값의 낮은 순서 바이트를 ASCII 문자로 변환하거나, 스택의 맨 위가 문자열인 경우 문자열의 첫 번째 문자로 대체한다.문자열의 빌드나 문자열 조작을 수행할 수 있는 방법은 를 사용하여 실행하는 것 이외에는 없다.x
명령 또는 를 사용하여 인쇄P
명령하다
그#
캐릭터는 줄의 끝까지 코멘트를 시작한다.
매크로스
그런 다음 레지스터와 스택 항목이 숫자뿐만 아니라 문자열로 허용함으로써 매크로가 구현된다.문자열은 인쇄할 수 있지만 실행될 수도 있다(즉, dc 명령의 시퀀스로 처리됨).예를 들어 매크로를 저장하여 하나를 추가한 다음 2를 곱하여 레지스터 m:
[1 + 2 *] sm
그리고 (사용하는)x
스택의 상단을 실행하는 명령)은 다음과 같이 사용할 수 있다.
3 lm x p
조건
마지막으로, 우리는 조건들을 제공하기 위해 이 매크로 메커니즘을 사용할 수 있다.명령어=r
스택에서 두 개의 값을 팝업하고 레지스터에 저장된 매크로를 실행하십시오.r
그들이 같을 때에만그래서 이 끈은equal
스택의 상단이 5인 경우에만:
[[equal]p] sm 5 =m
다른 조건들은>
,!>
,<
,!<
,!=
스택의 상위 두 값이 각각 더 크거나, 더 작거나, 더 작거나, 더 크거나, 같거나, 더 크거나, 같거나, 같지 않은 경우, 지정된 매크로를 실행한다.불평등 비교에서 피연산자의 순서는 산술의 순서와 반대라는 점에 유의한다.5 - 3 = 2
, 그러나 다음 이유로 레지스터의 내용을 실행한다.3 < 5
.
루프스
그런 다음 (조건부적으로) 스스로를 다시 실행하는 매크로를 정의함으로써 루핑이 가능하다.스택 상단의 단순 요인 설계는 다음과 같이 구현될 수 있다.
# F(x): return x! # if x-1 > 1 # return x * F(x-1) # 그렇지 않으면 # return x [d1-d1<F*]dsFxp
그1Q
명령이 매크로에서 종료되어 조기 복귀가 허용된다. q
두 가지 수준의 매크로(및 통화 스택에 두 개 미만의 레벨이 있는 경우 dc 자체)에서 종료. z
현재 스택 깊이를 다음으로 미십시오.z
작전
예
전체 스택 합계
이것은 레지스터에 저장된 매크로로 구현된다.a
스택에 하나의 값만 남을 때까지 매번 덧셈을 수행하면서 조건부로 자신을 호출한다.그z
연산자는 스택의 항목 수를 스택으로 푸시하는 데 사용된다.비교 연산자>
비교하는 데 있어 두 가지 값을 상쇄한다.
dc -e "1 2 4 8 16 100 0d[+2z]a]salaxp"
그리고 결과는 131이다.
모든 DC 식을 파일의 행으로 요약
베어 넘버는 유효한 dc 식이므로, 이것은 각 행이 하나의 숫자를 포함하는 파일의 합계에 사용될 수 있다.
이것은 레지스터에 저장된 매크로로 다시 구현된다.a
스택에 하나의 값만 남을 때까지 매번 덧셈을 수행하면서 조건부로 자신을 호출한다.
cat 파일 dc -e "0d[?+2z>a]살락스프"
그?
오퍼레이터는 입력 스트림에서 다른 명령을 읽는다.입력 라인에 십진수가 포함되어 있으면, 그 값이 스택에 추가된다.입력 파일이 파일 끝에 도달하면 명령은 null이며 스택에 값이 추가되지 않는다.
{ 에코 "5"; 에코 "7"; } dc -e "0d[?+2z>a]살락스프"
그리고 결과는 12.
입력 라인은 복잡한 dc 명령어일 수도 있다.
{ 에코 "3 5 *"; 에코 "4 3 *"; 에코 "5dd++"; } dc -e "0d[?+2z>a]살락스프"
그리고 결과는 42.
dc는 임의의 정밀도를 지원하므로, AWK의 유사하게 간결한 솔루션과 달리 입력 스트림에 포함된 라인이 아무리 많아도 숫자 오버플로나 정밀도 상실에 대한 우려가 없다는 점에 유의한다.
이 솔루션의 단점은 입력 스트림의 빈 라인(기술적으로, 스택에 적어도 하나의 숫자 값을 추가하지 않는 입력 라인)과 마주칠 때 발생하는 루프 스톱, 그리고 음수를 처리하기 위해서는 dc의 비표준 니카티 때문에 입력 스트림의 '_'로 부정적인 기호를 나타내는 '-'의 선행 인스턴스를 변경해야 한다는 것이다.사인하다그?
dc의 연산자는 빈 줄을 파일의 끝에서 읽는 것을 구별할 수 있는 깨끗한 방법을 제공하지 않는다.
단위 변환
dc에서 비교적 간단한 프로그램의 예로서, 이 명령어(1줄):
dc -e '[숫자(metres)를 입력하거나, 0을 입력하여 exit]psj[q]sz[lhx?d0=z10k39]370079*.5+0k12~1/rn[피트]PN[인치]P10Pdx]dx'
미터에서 피트, 인치까지의 거리를 변환한다. 그것의 대부분은 입력을 요구하는 것과 관련이 있다. 적절한 형식으로 출력을 인쇄하고 다른 숫자를 변환하기 위해 반복한다.
최대공통점
예를 들어, 다음은 GCD를 찾기 위한 유클리드 알고리즘의 구현이다.
dc -e '?[DSarLa%d0<a]dsax+p' # 최단 dc -e '[a=]P?[b=]P?[dSarla%d0<a]dsax+[]GCD:]Pp' # 읽기 쉬운 버전
요인
입력 값의 요인 계산, != = i
dc -e '?[q]sQ[d1=Qd1-lFx*]dsFxp'
dc 단위의 쿼인
프로그래밍 언어 dc에도 쿼터가 있다; 출력으로 소스 코드를 생성하는 프로그램이다.
dc -e '[91Pn[dx]93Pn]dx' dc -e '[91PP93]P[dx]P]dx'
모든 소수점 인쇄
2p3p[dl!d2+s!%0] 에 메아리치다.=@l!l^!<#s#[s/0ds^]s@[p]s&[ddvs^3s!l#x0<&2+l.x]ds.x' dc.
이 프로그램은 미셸 샤르펜티에가 썼다.프라임 숫자의 순서를 출력한다.하나의 기호로 단축할 수 있다는 점에 유의하십시오. 이것이 최소 해결책인 것 같다.
2p3p[dl!d2+s!%0] 에 메아리치다.=@l!l^!<#s#[0*ds^]s@[p]s&[ddvs^3s!l#x0<&2+l.x]ds.x' dc.
정수 인자화
dc -e '[n=]P?[p]s2[lip/dli%0=1dvsr]s12sid2%0=13sidvsr[dli%0=1lrli2+dsi!]dcds.xd1<2]
이 프로그램도 미셸 샤르펜티에가 썼다.[6]
더 짧은 것이 있다.
dc -e "[n=]P?[lfp/dlf%%0=Fdvsr]sF[dsf]sJdvsr2sf[dlf%0]=Flfdd2%+1+sflr<Jd1<M]dsMx"
더 빠른 솔루션(200비트 번호 2-1로200 시도)2 200^1-
)
dc -e "[n=]P?[lfp/dlf% 0=Fdvsr]sFdvsr2sfd2%0=F3sfd3%0=F5sf[dlf%0]=Flfd4+sflr>M]sN[dlf%0]=Flfd2+sflr>N]dsMx[p]sMd1<M"
상수에 대한 액세스가 레지스터 액세스로 대체되는 경우 후자는 더욱 속도를 높일 수 있다는 점에 유의하십시오.
dc -e "[n=]P?[lfp/dlf%l0=Fdvsr]sF2s2dvsr2sf4s4d2%0=F3sfd3%0=F5sf[dlf%l0=Flfdl4+sflr]M]sN[dlf%l0=Flfdl2+sflr]N]dsMx[p]sM"
Diffie-Hellman 키 교환
Perl 스크립트에 포함된 더 복잡한 dc 사용 예제는 Diffie-를 수행한다.헬먼 키 교환.이는 ITAR 토론회에서 Cyperpunks의 시그니처 블록으로 인기를 끌었는데, 여기서 짧은 스크립트는 Unix 유사 운영체제에서 Perl과 dc의 유비쿼터스 프로그램만으로 실행할 수 있었다.[7]
#!/usr/bin/perl -export-a-crypto-system-sig Diffie-Hellman-2-line ($g, $e, $m) = @ARGV, $m 죽다 "$0 gen exp mod\n"; 인쇄하다 'echo "16dio1[d2%Sa2/d0<X+d*La1=z\U$m%0]SX$e"[$g*]\EszlXx+p dc"
코멘트 버전은 조금 더 이해하기 쉬우며 루프, 조건 및 구성 요소를 사용하는 방법을 보여준다.q
매크로에서 돌아오라는 명령GNU 버전의 dc를 사용하면
명령은 X 함수를 쓸 필요 없이 임의의 정밀 모듈형 지수를 수행하는 데 사용될 수 있다.
#!/usr/bin/perl 나의 ($g, $e, $m) = 지도를 그리다 { "\U$_" } @ARGV; 죽다 "$0 gen exp mod\n" ~하지 않는 한 $m; 인쇄하다 'g 달러 $e m dc -e' # 육각 입출력 16다이오 # 한 줄에 stdin에서 m, e, g를 읽는다. ?SmSeSg # 함수 z: 리턴 g * 스택 상단 [lg*]sz # 기능 Q: 스택 상단을 제거하고 리턴 1 [sb1q]sQ # 함수 X(e): 재귀 계산 g^e % m # sm^Lm%와 같지만 임의로 큰 지수를 처리한다. # 입장 시 쌓기: e # 출구에 쌓기: g^e % m # e는 매우 클 수 있으므로, g^e % m ==라는 속성을 사용한다. # if( e == 0 ) # 귀환 1 # x = (g^(e/2) ^ 2 # if( e % 2 == 1 ) # x *= g # 리턴 x % [ d 0=Q # e=0일 경우 1을 반환(그렇지 않으면 스택: e) d 2% Sa # a에 e%2 저장(스택: e) 2/ # 계산 e/2 lxx # X(e/2) 호출 d* # 계산 X(e/2)^2 e%2==1인 경우 la1=z #에 g를 곱한다. lm % # 계산(g^e) % m ] SX le # 레지스터에서 e 로드 lXx # 계산 g^e % m p # 결과 출력 '`;
참고 항목
참조
- ^ 계산기 – Linux 사용자 명령어 : 임의의 정밀도
- ^ a b McIlroy, M. D. (1987). A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 (PDF) (Technical report). CSTR. Bell Labs. 139.
- ^ "The sources for the manual page for 7th Edition Unix dc".
- ^ Ritchie, Dennis M. (Sep 1979). "The Evolution of the Unix Timesharing System". Archived from the original on 2010-05-06.
- ^ Brian Kernighan and Ken Thompson. A nerdy delight for any Vintage Computer Fest 2019 attendee: Kernighan interviewing Thompson about Unix. YouTube. Event occurs at 29m45s. Retrieved September 3, 2019.
- ^ "Advanced Bash-Scripting Guide, Chapter 16, Example 16-52 (Factorization)". Retrieved 2020-09-20.
- ^ Adam Back. "Diffie–Hellman in 2 lines of Perl". Retrieved 5 Jan 2009.
외부 링크
- Debian GNU/리눅스 저장소의 패키지 dc
- Plan 9 Programmer's Manual, 1권 –
- 기본 윈도우즈 bc 포트(dc 포함)
- 웹페이지에 포함된 dc