부 = 떠있다 = float
부동소수점(浮動小數點, floating point) 또는 떠돌이 소수점 방식
실수를 컴퓨터상에서 근사하여 표현할 때 소수점의 위치를 고정하지 않고 그 위치를 나타내는 수를 따로 적는 것으로, 유효숫자를 나타내는 가수(假數)와 소수점의 위치를 풀이하는 지수(指數)로 나누어 표현한다.
부동소수점방식을 컴퓨터에 표현하기 위해서는 표현방식이 다름.
지수는 exponet임. 그래서 e를 따서 지수가 있음을 표현
https://www.youtube.com/watch?v=Ox1lpw7VyAg
정수를 표현하는 방식
일반적으로 사람이 표현하는 숫자 123을 표현하는 방식에는 여러가지가 있습니다. 우리가 일상적으로 사용하는 숫자 표현방식은 10진수입니다. 123을 여러가지 표현방식으로 나타내면 아래와 같습니다. 자세한 진법 변환 방법은 아래 참고 자료에 첨부하겠습니다.
- 16진수 : 7B
- 10진수 : 123
- 8진수 : 173
- 2진수 : 1111011
- http://10000calculator.com/%EC%A7%84%EB%B2%95%EB%B3%80%ED%99%98-%EB%B0%A9%EB%B2%95/
진법계산
진법계산및 진법변환에대한 설명을 하는 글입니다. 진법이란 수체계입니다. 가장 많이 이야기되는 2진법, 8진법, 16진법을 기준으로 설명하였습니다. 2진법은 컴퓨터가 사용하는 수체계입니다. 0
10000calculator.com
컴퓨터가 실수를 표현하는 방식
2진수 표현
컴퓨터는 숫자를 표현할 때 기본적으로 2진수를 사용합니다.
아래 표를 참고해서 숫자를 나타내 보면
- 13 = 8 + 4 + 1 이므로 해당 자리 숫자를 1로 표현하고 나머지는 0으로 표현합니다. 그러면 1101이 됩니다.
- 0.75 = 0.5 + 0.25 이므로 0.11 로 표현할 수 있습니다.
이렇게 쉽게 끝나면 얼마나 좋을까요! ㅠㅠ
263.3 같은 실수를 2진수로 표현해 보면
(상세 방법은 유튜브 영상에 자세히 나와 있습니다.)
- 263 => 100000111
- 0.3 => 0.01001100110011......(0011)의 무한 반복입니다.
이렇게 2진수로 표현하지 못하는 소수가 발생합니다. 어쩔 수 없이 컴퓨터에는 표현할 수 있는 가장 근사치의 값이 저장됩니다.
이 근사 값을 저장하는 방법에는 두 가지가 있습니다.
고정 소수점
- 정수를 표현하는 비트 수와 소수를 표현하는 비트 수를 미리 정해 놓고 해당 비트 만큼만 사용해서 숫자를 표현하는 방식
- 예) 실수 표현에 4byte(32bit)를 사용하고 그 중 부호(아래에서 괄호로 표시) 1bit, 정수 16bit, 소수 15bit를 사용하도록 약속해 놓은 시스템에 있다고 가정합니다. 이렇게 약속 된 시스템에서 263.3을 표현하면 (0)0000000100000111.010011001100110 이렇게 표현됩니다.
- 정수를 표현하는 bit를 늘리면 큰 숫자를 표현할 수 있지만 정밀한 숫자를 표현하긴 힘듭니다. 그래서 소수를 표현하는 bit를 늘릴 경우 정밀한 숫자를 표현할 수 있지만 큰 숫자를 표현하지 못합니다.
이런 문제를 해결하기 위해서 소수점을 고정하지 않고 둥둥 떠 다닐 수 있게 하는 부동 소수점(floating point)을 사용하고 있습니다.
부동 소수점
부동 소수점을 표현하는 방식도 정하는 방식에 따라 다를 수 있지만 일반적으로 사용하고 있는 방식은 IEEE에서 표준으로 제안한 방식입니다.
우선 고정 소수점으로 나타낸 263.3을 2진수 부동 소수점 방식으로 변환해 보겠습니다. 100000111.010011001100110... 으로 표현되던 것을 맨 앞에 있는 1 바로 뒤로 소수점을 옮겨서 표현하도록 변환합니다. 그러면 1.00000111010011001100110... * 2^8(2의 8승) 으로 표현 됩니다.
- 2^8의 8을 지수라고 하고 하늘색 부분에 기록합니다. (IEEE 754 표현 방식에서는 127 + 지수를 기록합니다.)
- 소수점 이후 숫자열 전체를 가수라고 하고 연두색 부분에 기록합니다.
이 방식에 따라서 263.3을 기록하면
- 부호 비트(1 bit) : 0 (양수)
- 지수 비트(8 bit) : 10000111 (127 + 8 = 135)
- 가수 비트(23 bit) : 00000111010011001100110
이렇게 표현할 수 있습니다.
하지만! 여기서도 0.010011001100110은 정확히 0.3을 나타낼 수는 없습니다. 10진수로 나타내 보면 0.29998779296875을 나타냅니다.
부동 소수점 오류 예
0.1을 100번 더하면 10이 나와야 되는데...
0.1을 정확히 표현할 수 없기 때문에 발생하는 오류입니다.
JAVA
Python
C
만약 이렇게 오류가 발생할 수 밖에 없는 부동소수점 연산을 블록체인 상에서 사용한다면 어떤 일이 벌어질까요? Token Decimal이 18자리인 EOS의 경우 0.3 EOS를 전송했는데, 갑자기 중간에 0.0000122070312499889 EOS가 훅~ 증발해 버립니다. ㅠㅠ
그래서 이런 일이 일어난 것을 방지하기 위해서 블록체인 구현 시 floating point 연산 지원을 하지 않습니다. 그럼 어떻게 소수점 단위로 코인(토큰)을 주고 받을 수 있을까요?
블록체인 구현 시 부동 소수점 처리
비트코인
- 분할 가능 범위 : 소수점 아래 8자리
- 0.00000001 BTC = 1 Satoshi
- 1 BTC = 100000000 Satoshi
이더리움
- 분할 가능 범위 : 소수점 아래 18자리
- 0.000000000000000001 Ether = 1 Wei
- 1 Ether = 100000000000000000 Wei
참고로 Gas비 계산에 사용되는 Gwei는
- 1 Gwei = 1000000000 Wei
입니다.
고정 소수점
- 정수를 표현하는 비트 수와 소수를 표현하는 비트 수를 미리 정해 놓고 해당 비트 만큼만 사용해서 숫자를 표현하는 방식
- 예) 실수 표현에 4byte(32bit)를 사용하고 그 중 부호(아래에서 괄호로 표시) 1bit, 정수 16bit, 소수 15bit를 사용하도록 약속해 놓은 시스템에 있다고 가정합니다. 이렇게 약속 된 시스템에서 263.3을 표현하면 (0)0000000100000111.010011001100110 이렇게 표현됩니다.
- 정수를 표현하는 bit를 늘리면 큰 숫자를 표현할 수 있지만 정밀한 숫자를 표현하긴 힘듭니다. 그래서 소수를 표현하는 bit를 늘릴 경우 정밀한 숫자를 표현할 수 있지만 큰 숫자를 표현하지 못합니다.
이런 문제를 해결하기 위해서 소수점을 고정하지 않고 둥둥 떠 다닐 수 있게 하는 부동 소수점(floating point)을 사용하고 있습니다.
부동 소수점
부동 소수점을 표현하는 방식도 정하는 방식에 따라 다를 수 있지만 일반적으로 사용하고 있는 방식은 IEEE에서 표준으로 제안한 방식입니다.
우선 고정 소수점으로 나타낸 263.3을 2진수 부동 소수점 방식으로 변환해 보겠습니다. 100000111.010011001100110... 으로 표현되던 것을 맨 앞에 있는 1 바로 뒤로 소수점을 옮겨서 표현하도록 변환합니다. 그러면 1.00000111010011001100110... * 2^8(2의 8승) 으로 표현 됩니다.
- 2^8의 8을 지수라고 하고 하늘색 부분에 기록합니다. (IEEE 754 표현 방식에서는 127 + 지수를 기록합니다.)
- 소수점 이후 숫자열 전체를 가수라고 하고 연두색 부분에 기록합니다.
이 방식에 따라서 263.3을 기록하면
- 부호 비트(1 bit) : 0 (양수)
- 지수 비트(8 bit) : 10000111 (127 + 8 = 135)
- 가수 비트(23 bit) : 00000111010011001100110
이렇게 표현할 수 있습니다.
하지만! 여기서도 0.010011001100110은 정확히 0.3을 나타낼 수는 없습니다. 10진수로 나타내 보면 0.29998779296875을 나타냅니다.
부동 소수점 오류 예
0.1을 100번 더하면 10이 나와야 되는데...
0.1을 정확히 표현할 수 없기 때문에 발생하는 오류입니다.
JAVA
Python
C
만약 이렇게 오류가 발생할 수 밖에 없는 부동소수점 연산을 블록체인 상에서 사용한다면 어떤 일이 벌어질까요? Token Decimal이 18자리인 EOS의 경우 0.3 EOS를 전송했는데, 갑자기 중간에 0.0000122070312499889 EOS가 훅~ 증발해 버립니다. ㅠㅠ
그래서 이런 일이 일어난 것을 방지하기 위해서 블록체인 구현 시 floating point 연산 지원을 하지 않습니다. 그럼 어떻게 소수점 단위로 코인(토큰)을 주고 받을 수 있을까요?
블록체인 구현 시 부동 소수점 처리
비트코인
- 분할 가능 범위 : 소수점 아래 8자리
- 0.00000001 BTC = 1 Satoshi
- 1 BTC = 100000000 Satoshi
이더리움
- 분할 가능 범위 : 소수점 아래 18자리
- 0.000000000000000001 Ether = 1 Wei
- 1 Ether = 100000000000000000 Wei
참고로 Gas비 계산에 사용되는 Gwei는
- 1 Gwei = 1000000000 Wei
입니다.
'coding > coding etc' 카테고리의 다른 글
블루스크린 irql not less or equal 오류 날 때 (0) | 2022.05.13 |
---|---|
iptime 내 ip 고정하기 (0) | 2022.05.04 |
tmp 파일 여는 방법 (0) | 2022.04.28 |
ppt 이미지 내보내기 해상도 올리는 법(레지스트리 편집기) (0) | 2022.04.27 |
~/(홈디렉터리) ../ ./ 절대경로, 상대경로 (0) | 2022.04.22 |