IEEE754의 미묘한 수
±0.0, ±Inf, NaN
소스 프로그램
program float2
implicit none
real :: xp, xm, yp, ym, zp, zm
integer :: k
!
! +0.0, -0.0 Minus Zero
!
xp = +0.0
xm = -0.0
print *, xp, xm
print *, log(cmplx(2.0, xp)), log(cmplx(2.0, xm))
print *
!
! +Inf, -Inf
!
yp = 1.0 / xp
ym = 1.0 / xm
print *, yp, ym
print *, atan(yp), atan(ym)
print *
!
! NaN
!
zm = sqrt(-1.0)
k = transfer(zm, k)
k = iand(k, b'01111111111111111111111111111111')
zp = transfer(k, zp)
print *, zp, zm
print '(2b33.32)', zp, zm
print *
!
! +NaN, -NaN ???
!
print *, sign(1.0, zp), sign(1.0, zm)
!
end program float2
실행 결과
0.0000000E+00 -0.0000000E+00
(0.6931472,0.0000000E+00) (0.6931472,-0.0000000E+00)
Infinity -Infinity
1.570796 -1.570796
NaN NaN
01111111110000000000000000000000 11111111110000000000000000000000
1.000000 -1.000000
続行するには何かキーを押してください . . .
설명
±Zero
IEEE754의 수의 체계에는 +0.0 와 -0.0 의 2 개의 제로가 있습니다. 이것을 중복으로 넌센스로 보는 방향도 있지만, 예를 들면 다가 복소함수의 리만면의 컷 라인의 전후를 구별하는 등의 목적으로 필요하다고 하는 방향도 있습니다. 여기에서는 복소 로그 함수가 허수부의 음수와 음수를 결과에 반영하는 것을 봅니다.
±Inf(Infinity)
IEEE754 이전에는 0으로 나누면 "division by zero"의 인터럽트에 의한 프로그램의 강제 종료를 일으켰습니다. 로 계산이 계속됩니다. 여기서 Arctan(+Inf) 은 $\pi/2$ 를, Arctan(-Inf) 는 $-\pi/2$ 를 반환하는 것을 보고 있습니다.
NaN (Not A Number)
IEEE754 이전에는 sqrt(-1.0)과 같은 정의역을 벗어난 연산은 "domain error"의 인터럽트에 의한 프로그램의 강제 종료를 일으켰습니다만, IEEE754에서는 NaN이라는 요소가 수의 체계 안에 도입 결과를 NaN으로 계산이 계속됩니다. NaN 과 그 외의 수의 연산은 모두 NaN 라고 정의되고 있습니다. 따라서 일단 NaN이 발생하면 그 이후의 결과는 모두 NaN으로 덮여 버립니다. (또한 인수를 복소수로 주면 함수 sqrt 는 복소수(0.0,1.0)를 돌려줍니다.)
그러나 이상하게도 Intel Fortran의 Sign 함수를 사용하면 NaN의 부호 비트를 읽고 결과를 일반 수로 만들 수 있습니다. 이것이 Intel Fortran만의 기행인지, Fortran의 규격에 의한 것인지, IEEE754의 규격에 의한 것인지, 현재는 잘 모르겠습니다.
또한 NaN 은 정의보다 비트열로서는 일의는 아니고 많이 있습니다. 부호 비트적으로 정부분 동수가 있습니다만, NaN 그 자체에는 부호는 없습니다.
Intel Fortran의 참고 사항
±0.0을 사용하려면 옵션 사양이 필요합니다.
IEEE754 모형
6bits => 1bit: 부호, 2bits: 지수부(2^0,2^1), 3bits: 가수부(1/2,1/4,1/8)
비트 표현
000
001
010
011
100
101
110
111
000
+0.000
+1.000
+2.000
+Inf
-0.000
-1.000
-2.000
-Inf
001
+0.125
+1.125
+2.250
NaN
-0.125
-1.125
-2.250
NaN
010
+0.250
+1.250
+2.500
NaN
-0.250
-1.250
-2.500
NaN
011
+0.375
+1.375
+2.750
NaN
-0.375
-1.375
-2.750
NaN
100
+0.500
+1.500
+3.000
NaN
-0.500
-1.500
-3.000
NaN
101
+0.625
+1.625
+3.250
NaN
-0.625
-1.625
-3.250
NaN
110
+0.750
+1.750
+3.500
NaN
-0.750
-1.750
-3.500
NaN
111
+0.875
+1.875
+3.750
NaN
-0.875
-1.875
-3.750
NaN
대응표
| 上位ビット |
------------------------------
아래|+0.0 +inf |-0.0 -Inf|
위| 비 正 | 비 正 |
비| 正 規 N| 正 規 N |
| 規 化 a| 規 化 a |
토| 化 数 N| 化 数 N |
数 |
------------------------------
수직선 표시
-Inf 正規化数 非正規化数 正規化数 +Inf
|-|-+-+-+-+-+-+-|+++++++|.......|.......|+++++++|-+-+-+-+-+-+-|-|
-Huge=-3.750 -2.0 -1.0 0.0 +1.0 +2.0 +Huge=+3.75
Reference
이 문제에 관하여(IEEE754의 미묘한 수), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/cure_honey/items/f4ad7bae9f861eaba2df
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
program float2
implicit none
real :: xp, xm, yp, ym, zp, zm
integer :: k
!
! +0.0, -0.0 Minus Zero
!
xp = +0.0
xm = -0.0
print *, xp, xm
print *, log(cmplx(2.0, xp)), log(cmplx(2.0, xm))
print *
!
! +Inf, -Inf
!
yp = 1.0 / xp
ym = 1.0 / xm
print *, yp, ym
print *, atan(yp), atan(ym)
print *
!
! NaN
!
zm = sqrt(-1.0)
k = transfer(zm, k)
k = iand(k, b'01111111111111111111111111111111')
zp = transfer(k, zp)
print *, zp, zm
print '(2b33.32)', zp, zm
print *
!
! +NaN, -NaN ???
!
print *, sign(1.0, zp), sign(1.0, zm)
!
end program float2
0.0000000E+00 -0.0000000E+00
(0.6931472,0.0000000E+00) (0.6931472,-0.0000000E+00)
Infinity -Infinity
1.570796 -1.570796
NaN NaN
01111111110000000000000000000000 11111111110000000000000000000000
1.000000 -1.000000
続行するには何かキーを押してください . . .
6bits => 1bit: 부호, 2bits: 지수부(2^0,2^1), 3bits: 가수부(1/2,1/4,1/8)
비트 표현
000
001
010
011
100
101
110
111
000
+0.000
+1.000
+2.000
+Inf
-0.000
-1.000
-2.000
-Inf
001
+0.125
+1.125
+2.250
NaN
-0.125
-1.125
-2.250
NaN
010
+0.250
+1.250
+2.500
NaN
-0.250
-1.250
-2.500
NaN
011
+0.375
+1.375
+2.750
NaN
-0.375
-1.375
-2.750
NaN
100
+0.500
+1.500
+3.000
NaN
-0.500
-1.500
-3.000
NaN
101
+0.625
+1.625
+3.250
NaN
-0.625
-1.625
-3.250
NaN
110
+0.750
+1.750
+3.500
NaN
-0.750
-1.750
-3.500
NaN
111
+0.875
+1.875
+3.750
NaN
-0.875
-1.875
-3.750
NaN
대응표
| 上位ビット |
------------------------------
아래|+0.0 +inf |-0.0 -Inf|
위| 비 正 | 비 正 |
비| 正 規 N| 正 規 N |
| 規 化 a| 規 化 a |
토| 化 数 N| 化 数 N |
数 |
------------------------------
수직선 표시
-Inf 正規化数 非正規化数 正規化数 +Inf
|-|-+-+-+-+-+-+-|+++++++|.......|.......|+++++++|-+-+-+-+-+-+-|-|
-Huge=-3.750 -2.0 -1.0 0.0 +1.0 +2.0 +Huge=+3.75
Reference
이 문제에 관하여(IEEE754의 미묘한 수), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/cure_honey/items/f4ad7bae9f861eaba2df텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)