파이썬 공부 중 아래와 같은 부분을 공부하고 있었다.
그런데!?!?
print('%.5f' %(987.123456789))
나의 요청한 작업 = 소수점 밑에 5자리까지만 보여줘
결과 = 987.12346
왜!!!!!!! 내가 987.123456789 라는 값에서 소수점 밑 5자리까지만 출력해 달라고 했는데!!!
내가 원한 값은!!!!!! 987.12345 인데!!!!!
왜!!!!!!!!!!!!! 987.12346을 주는 건데!!!!!!!!!
어?? javascript에서도 동일하게 소수점 밑을 자르면 반올림하네.
위와 같은 현상은 왜 발생하는가???
🤨 내 생각을 흐름….
💬 아… 파이썬… 진짜… 출력도 제대로 못하네.
💬 자바스크립트는 제대로 나올 텐데. 자바스크립트에서 출력해 보자.
💬 뫄!!?!??!?!? 자바스크립트에서도 반올림해서 출력되네!!!! XXX이거 몽가 이따. 참을 수 없다.
도와줘!!!GPT!!!! 이거 왜 이런거야아아아아!!!!!!!
💡 🤖 기본적으로 부동 소수점 숫자를 처리할 때 반올림(rounding)을 수행하기 때문입니다.
- 라고 GPT님이 말씀하셨습니다.
부동 소수점이 뭔데!!!!!
아예 모를 땐 뭐다? 사전 검색을 해야 한다.
명사
• 1 물이나 공기 중에 떠서 움직임.
• 2 고정되어 있지 않고 움직임.
예 : 부동 인구.
• 3 진득하지 못하고 들뜸.
💬 내 해석 = 부동 소수점 = 뭔가 고정되지 않은 소수점 인가봉가... 그러면 고정 소수점도 있겠네?
🔨고정 소수점 = 소수 점을 고정해 정수부와 소수부를 각각 저장하는 것
그.러.니.까 고정 소수점 / 부동 소수점이 뭐냐고오..…….
이걸 이해하기 위해 지금 필요한 거는?
컴퓨터가 메모리에 숫자를 저장하는 방법
- 컴퓨터는 모든 것을 어떻게 저장한다? → 숫자로 저장한다.
- 어떤 숫자로 저장한다? → 2진수(0,1)로 저장한다.
- 2진수가 뭐다? → 0 또는 1이고, 컴퓨터는 0,1만 이해해서 처리한다.
- 그러면 컴퓨터가 이해하는 2진수를 어디다 저장한다? → 메모리에 저장한다.
- 메모리의 저장 단위는 뭐다? → 비트(bit)다.
- 비트(bit)는 뭐다? → 컴퓨터에 저장되는 가장 작은 공간(단위)이다.
- 그러면 비트에는 어떻게 저장된다? → 1비트 안에는 컴퓨터가 이해하는 언어 0,1을 1개씩 저장한다.
** PC들의 기본 저장 처리 아키텍처는 32비트 또는 64비트이다.
그러면
32 비트라는 의미는? → 0 또는 1을 각각 한 번에 32개까지 저장/처리할 수 있다.
정리하면!?
💡 컴퓨터는 어떤 정보든 0,1로 변환(이진수)해서 메모리에 저장한다.
ex : 숫자 4를 저장하면 → 00000000 00000000 00000000 00000100
그리고 또 필요한 게 뭐다?
이진수 변환 방법
도와줘 GPT!!
양수를 이진수로 변환하는 방법
1. 숫자를 2로 나눈다.
2. 나머지를 기록한다. (나머지는 0 또는 1이 됩니다)
3. 몫을 2로 다시 나눈다. 이 과정을 몫이 0이 될 때까지 반복한다.
4. 기록한 나머지를 거꾸로 읽는다. (마지막 나머지부터 첫 번째 나머지까지)
예시: 숫자 18을 이진수로 변환하기
1. 18 ÷ 2 = 9 … 나머지 0
2. 9 ÷ 2 = 4 … 나머지 1
3. 4 ÷ 2 = 2 … 나머지 0
4. 2 ÷ 2 = 1 … 나머지 0
5. 1 ÷ 2 = 0 … 나머지 1
휴…그러면 모두 해치웠나?
그러면 우리는 2가지를 알았습니다.
- 컴퓨터가 저장하는 방식(0,1로 변환 후 저장)과 최소 저장 공간(32bit)
- 이진수 변환 방법
우리가 이걸 왜 알아야 할까요?
문제가 뭐였을까요?
문제는 3.123456789 라는 값에서, 소수점 이하 5자리까지만 출력하라고 했는데
값이 3.12345가 아니라 3.12346이 나온 게 문제였습니다.
그리고 우리는 이 문제가 무엇인지 파헤쳐보려 한 거였습니다.
문제를 파헤치는 첫 단계로 GPT의 답은 부동 소수점을 처리할 때 라운드 업을 한다라는 것을 해석해 보기 위해서였습니다.
다시 돌아갑니다.
부동 소수점 : 소수점이 고정되지 않은 수
소수점이 고정되어 있지 않다의 뜻은?
12323.4234234
2.434564356
245234646632425.134
이렇게 소수점이 여기저기 있을 수 있는 상황이 부동 소수점입니다.
12345.54321
이 수를 컴퓨터가 저장하기 위해서는
이진수(0,1)로 변환해야 합니다.
그리고 소수점이 어디에 찍히는지를 알아야 합니다.
그러면 우리는 또 알아봅시다. 소수는 어떻게 이진수로 변환하는지.
지피티야 0.2를 이진수로 변환하는 방법을 알려줘.
GPT 답>
0.2를 이진수로 변환하는 과정
1. 0.2 × 2 = 0.4
• 정수 부분: 0
• 남은 소수 부분: 0.4
2. 0.4 × 2 = 0.8
• 정수 부분: 0
• 남은 소수 부분: 0.8
3. 0.8 × 2 = 1.6
• 정수 부분: 1
• 남은 소수 부분: 0.6
4. 0.6 × 2 = 1.2
• 정수 부분: 1
• 남은 소수 부분: 0.2
5. 0.2 × 2 = 0.4
• 정수 부분: 0
• 남은 소수 부분: 0.4
이후 단계는 다시 반복됩니다: 0.4 → 0.8 → 1.6 → 0.6 → 1.2 → 0.2.
결과
이 패턴은 무한히 반복됩니다. 따라서, 0.2를 이진수로 표현하면:
\\text{0.2} \\approx \\text{0.0011} \\overline{0011}…
소수 부분을 이진수로 변화하는 방법은 2를 곱하고, 정수 부분을 가져가고
다시 2를 곱해서 0이 나올 때까지 반복합니다.
0.5를 이진수로 변환방법
0.5 x 2 = 1.0
소수자리가 0으로 끝났음
0.5 를 이진수로 변환하면 01로 끝
그래서 뭐 어쩌라고?
아니 소수 부분은 2진수로 딱 떨어져서 변환이 안된다고!!!!!!무한반복되는 경우들이 음청 많다고오!!!!!!!!
라고 하면 안 되니까….
그래서 소수의 경우 메모리(=32 비트)에 어떻게 이진수로 저장하느냐 하면.
-118.625 을 메모리에 저장해볼까요?
1. 우선 절대값으로 변환해요. 절대값으로 변환하면 118.625 에요.
2. 118을 이진수로 변환해요. 118을 이진수로 변환하면 1110110 이에요.
3. 그리고 나머지 소수점 부분을 이렇게 만들어요. 0.625
4. 이제 0.625를 이진수로 변환해요. 그러면 101 이에요.
5. 그러면 이제 이진수로 변환한 정수 부분과 소수부분을 합쳐볼까요? 1110110.101 이에요.
6. 이제 소수점을 이동시킬꺼에요. 맨 숫자 바로 뒤로요. 1.110110101
7. 이제 메모리(32비트)에 저장할꺼에요.
그런데 32개의 칸에 3가지로 나눠서 저장 할꺼에요.
첫 번째 칸 = 음수 인지 양수 인지 표시 (0 = 양수, 1 = 음수)
두 번째 칸 ~ 여덟 번째 칸 = 소수점의 원래 있던 곳 까지의 칸 수를 Bias를 더한 수 이진 수로 변환한 값을 저장
나머지 칸 = 이진수로 변환한 제일 앞자리를 뺀 나머지 이진수를 각 칸에 저장 / 남으면 0으로 채움
이렇게 저장을 하는 거예요 알겠죠?
그런데
0.625처럼 이진수로 딱 떨어지면 괜찮은데
0.2로 를 이진수로 저장하려고 변환하면 딱 떨어지지고 않고 무한반복합니다.
그.래.서!!!!!
딱 이진수로 딱 떨어지지 않는 소수는 32비트 안에 다 저장을 못합니다!!!!!!!!!
= 이 말은 컴퓨터는 0.2 같은 숫자를 저장할 때, 대충, 그 즈으으으으으으으으~음~~~ 유사한 숫자로 저장을 한다는 겁니다.
** tip_사실 이거 보면 금방 이해될 내용이었음 : https://www.youtube.com/watch?v=ZQDsWySjY6g
그러면 이제?
그러면 이제?
완전 처음으로 돌아가서 내가 한 행위가 뭐였더라?
print('%.5f' %(987.123456789))
나의 요청한 작업 = 소수점 밑에 5자리까지만 보여줘
결과 = 987.12346
이제 이해한걸 대입해봅니다.
💬 소수는 이진수로 정확하게 딱 떨어지지 않는 경우가 있어서 대충 그 즈음 비슷~~~~~~한 숫자로 저장한다.
💬 그런데 나는 987.123456789 이 숫자를 계산도 아니고, 그냥 소수점 이하 5번 까지만 보여달라고 했는데, 정확하게 저장지 못하는거랑 뭔 상관이야?
💬 아니!!!!! 이미 987.123456789 이미 이렇게 보여주고 있는데, 여기서 딱 소수점 이하 5자리까지만 끊어서, 97.12345 까지만 보여주는데 왜 반올림 하냐고!!!!!
그래서 여기저기 위 상황에 대해서 사람들에게 물어보았습니다.
💬 그래!!그래에!!!! 알겠고!!!!! 소수(실수)가 제대로 이진수로 변환이 안되어서 대충 비슷한 값으로 저장하는거 알겠는데. 이미 987.123456789 라고 보여줬고, 여기서 소수점 이하 다섯짜리까지만 보여달라는데 왜 반올림을 하냐고오오오오!!!!!!!!! 내가 시키지도 않았는데에에에!!!!!!!!!!
💬 (내 질문을 들은 인간 왈) : 컴퓨터는 원래 그래요.
.
....
........
............
💬 컴퓨터…..???? 컴퓨터의 정의가 뭐지…..???
컴퓨ː터, computer
명사
- 전자 회로를 이용한 고속 자동 계산기. 수 계산 이외에 자동 제어, 데이터 처리, 사무 관리, 언어나 화상(畵像)의 정보 처리 등 광범위하게 이용됨. 전자계산기(電子計算機). 셈틀.
계.산.기
계산 뜻 = (명사) 수를 헤아림
헤아리다 뜻 = (동사) 수량을 세다.
계산기 뜻 = 수량을 헤아리는 기계
내가 요청한 이 작업은 사실 계산이였다.
print('%.5f' %(987.123455789))
나의 요청한 작업 = 소수점 밑에 5자리까지만 보여줘
결과 = 987.12346
💻 컴퓨터 왈 :
너가 요청한 작업을 계산하려고 봤는데. 987.123456789 이 숫자를 사실 나는 애매하게 비슷한 값으로 가지고 있거든. 그런데 소수점 이하 5자리까지만 출력하면 의미가 애매해. 자 봐봐 987.12345 라고 보여주면 너는 오해 할 수 있어. 왜냐하면 원래 숫자는 987.123456789 인데, 987.12345 라고 하면, 원래 숫자는 이거보다 큰 수 인데 너가 987.1234500000으로 오해 할 수 있잖아. 그러니까 본 의미에 더 가까운 987.12346 으로 내가 라운드 업해서 보여줄께!!!!
그렇다, 컴퓨터는 프린터 / 모니터 처럼 출력기가 아니라 계산기였다.
내가 하는 요청은 다 계산이였다.
내 작업요청을 다시 수정하면
print('%.5f' %(987.123456789))
나의 요청한 작업 = 소수점 밑에 5자리까지 잘랐을 때, 정확히 어떤 의미를 가진 숫자인지 계산해서 보여줘.
결과 = 987.12346
[javascript도 마찬가지]
const number = 987.123456789;
console.log(number.toFixed(5));
결과 = 987.12346
나는 컴퓨터의 목소리가 들리기 시작했다.
'개발에 대해 얘기 합니다.' 카테고리의 다른 글
개발_메소드/함수가 도대체 뭐야!? (1) | 2024.09.15 |
---|---|
개발의 역사 속에서 "공유&믿음"의 의미에 대한 고찰 (0) | 2023.08.08 |
React_Portal사용과 여러 예시에 적힌 "children"에 관한 고찰 (0) | 2023.08.03 |
CSS 작성 시, 적용 우선 순위에 대한 고찰 (0) | 2023.08.01 |
"useEffect" 안에서 "SetTimeout & ClearTimeOut & return"의 관계 (0) | 2023.07.31 |