C

겁나 큰 숫자들에 대하여... 왜 이딴 값이 나오는가(안화남)

EYR 2022. 3. 18. 00:13

https://stackoverflow.com/questions/35893305/factorial-program-in-c-is-wrong-after-20

 

Factorial program in C is wrong after 20

It works up until 20 but if 21 is entered it returns 1419745... when 21 factorial is actually 51090942171709440000. I'm assuming that this is because of the unsigned long maxing out but where does ...

stackoverflow.com

이 모든것에 대한 요약.....

스택오버플로우없이 못살아

 

 

 

 

첫 번째 문제...

30!, 30 팩토리얼이 1409286144로 뜬다

10!이 3628800였는데?

int형으로 만들어 돌렸는데 이렇게 떴다.

계산기로 찾아보니까

http://mwultong.blogspot.com/2005/12/factorial-table-1100-0-100.html

 

수학] 팩토리얼 계산 표; Factorial Table 1~100 (0에서 100)까지 계승(階乘)

1에서 100까지의 팩토리얼을 구한 표입니다. (0! 까지 포함되어 있습니다. 0! 은 1 이라고 간주합니다.) (※ 스크롤 박스 사용법: 박스 안을 마우스로 클릭한 후, 키보드의 좌우 화살표키를 누르면

mwultong.blogspot.com

265252859812191058636308480000000

라는 값이라녜?

 

그때 딱 드는 예감

아 long이나 long long으로 하면 되는거 아닐까

https://docs.microsoft.com/ko-kr/cpp/cpp/data-type-ranges?view=msvc-170 

 

데이터 형식 범위

자세한 정보: 데이터 형식 범위

docs.microsoft.com

 

type int의 최대값은 2147483647

참고로 signed와 unsigned가 있는데, signed는 부호가 있는거, unsigned는 부호가 없는 것이다.

아마 첫번째 빗에 0 1로 음수 양수를 정하는게 아닌가 생각된다(추측, 찾아봐야 함)

때문에 부호가 있는 쪽은 부호가 없는 쪽보다 정확히 2배 적게 표기할 수 있다(양수 기준)

기본형은 signed를 포함하고 있다. 제곱같은 어차피 양수를 쓰는 계산들은 unsigned를 써도 될듯.

절대값이라던가

 

여튼 30!을 표기하기엔 너무 적은 양이다

 

long의 최대값은 2147483647

잉? 작다...

그렇다 아마 int형인 2바이트였는데 4바이트로 바뀌면서 그렇게 되었나 보다...

이미 대부분의 컴퓨터에선 int가 long까지 포함할수 있다는? 그런건가?

 

여튼 그럼 long long은 8바이트라 더 표현할 수 있다.

9223372036854775807

근데 이걸로도 265252859812191058636308480000000을 표기하기엔 너무 적다.

 

결론은 정수형 데이터들로는 표현할 수 없다는 거다.

 

 

그럼 뭘로 하냐.. double

 

double의 범위는 10의 380승까지 표기가 가능하다고 한다.

당연히 저정도는 표기할 수 있다.

 

 

 

 

 

https://dojang.io/mod/page/view.php?id=34 

 

C 언어 코딩 도장: 7.4 최솟값과 최댓값 표현하기

지금까지 오버플로우, 언더플로우와 자료형의 크기에 대해서 알아보았습니다. 이번에는 소스 코드에서 정수의 최솟값과 최댓값을 표현하는 방법을 알아보겠습니다. 유닛 맨 앞의 표 7‑1에서

dojang.io

int > %d

long > %ld

long long > %lld

단순하다...

 

double > %f

 

그래서 double로 하면?

265252859812191032188804700045312

짠 잘나온다

 

아니? 안나온다.

 

265252859812191058636308480000000
265252859812191032188804700045312

 

암만봐도 값이 다르다

얘가 사람도 아니고 틀릴수가 없는 컴퓨터인데 왜 이러지?

 

 

 

 

 

하고 찾아보면 이제

두번째 문제

 

 

 

 

 

 

찾아보니까...

https://pmj0403.tistory.com/entry/C%EC%96%B8%EC%96%B4%EC%97%90%EC%84%9C-%EC%8B%A4%EC%88%98%ED%98%95%EC%9D%98-%EC%B6%9C%EB%A0%A5-%EB%82%B4%EC%9A%A9%EC%9D%B4-%EC%A0%95%ED%99%95%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EC%9D%B4%EC%9C%A0

 

C언어에서 실수형의 출력 내용이 정확하지 않은 이유

실수형 출력 내용이 정확하지 않은 이유 ---------------------------------------- 제목: C언어에서 실수형의 출력 내용이 정확하지 않은 이유 ---------------------------------------- 실수형의 경우 숫자가..

pmj0403.tistory.com

여기서 진짜 잘 설명되어 있음.

 

대충 요약하자면 실수형 자료는 최대 정밀도와 유효 정밀도가 있고

double형은 15~16자리까지가 유효 정밀도라는 소리. 그 이후에는 오차가 생길 수 있다.

 

https://dojang.io/mod/page/view.php?id=738 

 

C 언어 코딩 도장: 85.4 실수 자료형의 오차

부동소수점 방식은 실수를 정확히 표현할 수 없는 문제가 있습니다. 다음 내용을 소스 코드 편집 창에 입력하고 실행해봅니다. float_rounding_error.c #include int main() { float num1 = 0.0f; float num2 = 0.1f; // 0

dojang.io

여기 설명도 도움이 꽤 된다.

 

https://devlog-wjdrbs96.tistory.com/254

 

[Java] float과 double의 차이는 무엇일까?

float vs double의 차이는? float과 double 모두 실수를 표현하기 위해 사용하는 자료형이라는 것은 알고 있을 것 입니다. 하지만 정확한 차이가 무엇이냐고 물어본다면 대답하기가 쉽지 않습니다...(애

devlog-wjdrbs96.tistory.com

여기도 참고했다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

이후 더 큰 숫자는 계산을 못하거나

https://kldp.org/node/23862

 

printf로 찍는데 inf 라고 나오는 건 왜이런가요? | KLDP

double curr_coll_rate; double last_coll_rate; double curr_avg_coll_rate; 이렇게 선언된 멤버 변수들을 아래처럼 printf로 출력하면 printf("rst_cw==>>: curr_coll_rate=%f, last_coll_rate=%f, curr_avg_coll_rate=%f\n", curr_coll_rate, last_co

kldp.org

이렇게 나온다

 

 

https://scripting.tistory.com/352

 

C 언어로 GMP 라이브러리를 이용하여 30! 까지 정확하게 계산하기

아래의 소스는 윈도우에서            Luna MinGW & GNU C 4.5.0 (gcc), 로 테스트되었다. long 타입으로는 13! 까지만 정확하계 계산되지만 GMP 를 이용한 계산은 아무리 큰 수의 곱셈이라도 정확히..

scripting.tistory.com

이런 방식들도 있는 모양

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=dnpc7848&logNo=220329515202 

 

[C/C++] 100! 처럼 큰수의 팩토리얼(Factorial) 구하기.

팩토리얼을 구하는 프로그램은 재귀함수를 배우면서 많이 만들어보는데 기본 자료형의 자릿수 한계 때문에 ...

blog.naver.com

나중에 참고하면 좋을듯

 

'C' 카테고리의 다른 글

[프로그래머스] 연습문제 도장깨기  (0) 2022.03.08
[프로그래머스] 두 정수 사이의 합  (0) 2022.03.08
[프로그래머스] 2016년  (0) 2022.03.06