-
Calculations | CS50 Week 1Computer Science/CS 50 Harvard 2021. 11. 6. 20:57
Harvard CS 50 강의를 한글로 정리한것입니다.
Calculator
앞서서 배운 내용들을 이용해서 간단한 계산을 하는 계산기를 만들어보자. 아래와 같은 커맨드를 실행하면, calculator.c 파일이 생성된다.
> code calculator.c
이후 아래와 같이 x, y 값을 유저에게서 받아서 간단한 덧셈을 하는 코드를 만들어보자.
#include <cs50.h> #include <stdio.h> int main(void) { int x = get_int("x: "); int y = get_int("y: "); printf("%i\n", x + y); }
이후 아래와 같이 컴파일을 한 후, 프로그램을 실행시킬 수 있다. 1과 2를 주었더니 3을 주었다.
> make calculator clang calculator.c -lcs50 -o calculator > ./calculator x: 1 y: 2 result: 3
만약 더한 값을 나중에 또 사용할 수 있도록 z 라는 variable을 생성해서 쓸수도 있다. 만약 한번만 프린트하고 말것이라면 필요 없지만, 더한 값을 또 사용한다면, 더하기를 다시 컴퓨터에게 시키는것은 비효율적이기때문에 저장을 해두고 다시 쓰는것이 좋다.
#include <cs50.h> #include <stdio.h> int main(void) { int x = get_int("x: "); int y = get_int("y: "); int z = x + y; printf("result: %i\n", z); }
여러사람이, 이 코드를 함께 작성하는것이고, 이 프로그램에 대해 전반적인 지식이 없는 대상이라면 아래처럼 코멘트를 달수도 있다.
#include <cs50.h> #include <stdio.h> int main(void) { // Prompt user for x int x = get_int("x: "); // Prompt user for y int y = get_int("y: "); // Add x and y, then save it to z int z = x + y; // print z as a result printf("result: %i\n", z); }
지금 이 프로그램은 간단하기때문에 한줄마다 코멘트를 다는것이 큰 의미가 없지만, 프로그램이 복잡해지면, 코멘트를 달아서 어떤 동작을 하는지 설명해줄 수 있다.
프로그램을 컴파일 할 때, calculator라고 모두 칠 필요 없이 make ca 정도까지만 치고, tab 키를 누르면 자동완성을 해주거나, ca로 시작하는 파일을 보여주고, 두가지 파일이 있다고 하면, 겹치지 않는 부분까지만 친 후 다시 tab 키를 누르면, 자동완성을 해주어서 시간을 절약할 수 있다.
Overflow
자, 다시 프로그램을 실행시키고 아래와같이 큰 숫자로 테스트해보자.
> ./calculator x: 1000000000 y: 1000000000 result: 2000000000
큰 숫자도 무리없게 계산하는 모습이다. 그렇다면 조금더 큰 숫자로 한다면?
> ./calculator x: 2000000000 y: 2000000000 result: -294967296
2,000,000,000(20억) 을 두번 더했더니, -294,967,296 라는 숫자가 나왔다. 즉, 오류를 만들어 낸것이다. int 라는 타입은 32 bits를 이용하는데, 약 40억의 숫자($2^32$)를 포함시킬 수 있는데, 숫자는 positive와 negative로 나눠지기 때문에, 약 20억의 negative와 약 20억의 positive를 나타낼 수 있다. 그렇기때문에, 20억을 2번 더했을 때, 계산에 실패한것이다. 왜냐하면 int에서는 2,147,483,647, 즉 $2^31 - 1$이 표현할 수 있는 가장 큰 숫자이다. 이 문제를 어떻게 해결할 수 있을까?
#include <cs50.h> #include <stdio.h> int main(void) { // Prompt user for x long x = get_long("x: "); // Prompt user for y long y = get_long("y: "); // Add x and y, then save it to z long z = x + y; // print z as a result printf("result: %li\n", z); }
integer보다 2배 많은 bits를 사용할 수 있는 long을 사용해보자. long에서는 $2^64$ 가지 숫자를 저장할 수 있기 때문에, $2^63 - 1$까지 사용할 수 있다.
> make calculator clang calculator.c -lcs50 -o calculator > ./calculator x: 2000000000 y: 2000000000 result: 4000000000
하지만 이 해법도 완벽한 솔루션은 아니다. 만약 아주 큰 숫자를 처리해야한다면?
> ./calculator x: 9000000000000000000 y: 9000000000000000000 result: -446744073709551616
위와같이 오류가 난다. 우리가 평상시 사용하는 계산기는 이런 큰 숫자까지는 처리하지 않기 때문에 괜찮지만, 슈퍼컴퓨터 또는 공학계산기는 이런것도 계산을 해야한다.
이것에 대해서는 여러가지 해법이 있는데, 공교롭게도 한 회사의 인터뷰 과정에서 위 문제를 해결하는 문제를 받은적이 있다. 간단하게 설명하면, char와 string을 이용해서 한자리씩 계산하고, string에 더해주는 방식으로 해결했다. 해법에 대해선 다음에 논의를 해보겠다.
Reference
'Computer Science > CS 50 Harvard' 카테고리의 다른 글
Loops, functions | CS50 Week 1 (0) 2021.11.06 Conditionals, Boolean expressions | CS50 Week 1 (0) 2021.11.06 Variables, syntactic sugar | CS50 Week 1 (0) 2021.11.06 Types, format codes, operators | CS 50 Week 1 (0) 2021.11.06 main, header files, commands | CS 50 Week 1 (0) 2021.11.06