Movatterモバイル変換


[0]ホーム

URL:


  ¥Û¡¼¥àÌܼ¡Á°¥Ú¡¼¥¸¤Ø¼¡¥Ú¡¼¥¸¤Øº÷°ú


¤³¤ÎÉÕÏ¿¤Ç¤Ï¡¢¤è¤¯¹Ô¤ï¤ì¤ëºî¶È¤ÎÎã¤ò¼¨¤·¤Þ¤¹¡£Îã¤Ï FORTRAN¡¢¤ª¤è¤Ó ANSI C ¤Ç½ñ¤«¤ì¤Æ¤ª¤ê¡¢¤½¤Î¿¤¯¤Ï¸½¥Ð¡¼¥¸¥ç¥ó¤Îlibm ¤Èlibsunmath ¤Ë°Í¸¤·¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤é¤ÎÎã¤Ï¡¢Solaris ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¾å¤Î C ¤ª¤è¤Ó FORTRAN ¥³¥ó¥Ñ¥¤¥é¤Ç¥Æ¥¹¥È¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

ÉâÆ°¾®¿ôÅÀ¿ô¤Î 16 ¿Êɽ¸½¤Î¸¡¾ÚÊýË¡¤òÎã¤Ç¼¨¤·¤Þ¤¹¡£³ÊǼ¤µ¤ì¤¿¥Ç¡¼¥¿¤Î 16 ¿Êɽ¸½¤ò¸«¤ë¤Ë¤Ï¡¢¥Ç¥Ð¥Ã¥¬¤ò»ÈÍѤ¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

°Ê²¼¤Î C ¤Î¥×¥í¥°¥é¥à¤Ç¤Ï¡¢ÇÜÀºÅ٤ζá»÷Ãͤò ¦Ð ¤ÈñÀºÅÙ¤Î̵¸ÂÂç¤Ë½ÐÎϤ·¤Þ¤¹¡£

#include <math.h>
#include <sunmath.h>
main() {
union {
floatflt;
unsignedun;
} r;
union {
doubledbl;
unsignedun[2];
} d;
/* ÇÜÀºÅÙ */
d.dbl = M_PI;
(void) printf("DP Approx pi = %08x %08x = %18.17e \n",
d.un[0], d.un[1], d.dbl);
/* ñÀºÅÙ */
r.flt = infinityf();
(void) printf("Single Precision %8.7e : %08x \n",
r.flt, r.un);
exit(0);
}

SPARC ¤Ç¤Ï¡¢¾åµ­¤Î¥×¥í¥°¥é¥à¤Î½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

DP Approx pi = 400921fb 54442d18 = 3.14159265358979312e+00
Single Precision Infinity : 7f800000

¼¡¤Î FORTRAN ¥×¥í¥°¥é¥à¤Ï¡¢ºÇ¾®¤ÎÀµµ¬¿ô¤ò¤½¤ì¤¾¤ì¤Î·Á¼°¤Ç½ÐÎϤ·¤Þ¤¹¡£

     program print_ieee_values
c
c implicit ʸ¤Ï¡¢f77_floatingpoint µ¿»÷ÁȤ߹þ¤ß´Ø¿ô¤¬¡¢
c Àµ¤·¤¤·¿¤ÇÀë¸À¤µ¤ì¤Æ¤¤¤ë¤«¤ò³Îǧ¤·¤Þ¤¹¡£
c
     implicit real*16 (q)
     implicit double precision (d)
     implicit real (r)
     real*16 z
     double precision x
     real r
c
     z = q_min_normal()
     write(*,7) z, z
 7   format('min normal, quad: ',1pe47.37e4,/,'   in hex ',z32.32)
c
     x = d_min_normal()
     write(*,14) x, x
 14  format('min normal, double: ',1pe23.16,' in hex ',z16.16)
c
     r = r_min_normal()
     write(*,27) r, r
 27  format('min normal, single: ',1pe14.7,' in hex ',z8.8)
c
     end

SPARC ¤Ç¤Ï¡¢Âбþ¤¹¤ë½ÐÎϤ¬¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

min normal, quad:   3.3621031431120935062626778173217526026E-
4932
   in hex 00010000000000000000000000000000
min normal, double:2.2250738585072014-308 in hex 0010000000000000
min normal, single:1.1754944E-38 in hex 00800000

(x86 ¤Ç¤Ï¡¢FORTRAN ¥³¥ó¥Ñ¥¤¥é¤Ïreal*16 ·¿¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó¡£Á°µ­¤ÎÎã¤ò x86 ¤Ç¼Â¹Ô¤¹¤ë¾ì¹ç¤Ï¡¢real*16 Àë¸À¤È¡¢4 ÇÜÀºÅÙ¤ÎÃͤη׻»¤È½ÐÎϤò¹Ô¤¦¥³¡¼¥É¤òºï½ü¤·¤Æ¤¯¤À¤µ¤¤¡£)

¤³¤ÎÀá¤Ç¤Ï¡¢¿ô³Ø¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô¤ò»ÈÍѤ·¤¿Îã¤ò¼¨¤·¤Þ¤¹¡£

¼¡¤ÎÎã¤Ç¤Ï¡¢¿ô¤ÎÇÛÎó¤òÀ¸À®¤¹¤ëÍð¿ô´Ø¿ô¤ò¸Æ¤Ó½Ð¤·¡¢Í¿¤¨¤é¤ì¤¿¿ô¤ÎEXP ¤ò·×»»¤¹¤ë¤Î¤Ë¤«¤«¤ë»þ´Ö¤ò¬Äꤹ¤ë´Ø¿ô¤ò»ÈÍѤ·¤Þ¤¹¡£

#ifdef DP
#define GENERIC double precision
#else
#define GENERIC real
#endif
#define SIZE 400000
      program example
c
      implicit GENERIC (a-h,o-z)
      GENERIC x(SIZE), y, lb, ub
      real time(2), u1, u2
c
c [-ln2/2,ln2/2] ¤Ë¤ª¤±¤ëÍð¿ô¤Ç¤Î EXP ¤ò·×»»
      lb = -0.3465735903
      ub = 0.3465735903
c
c Íð¿ô¤ÎÇÛÎó¤òÀ¸À®
#ifdef DP
      call d_init_addrans()
      call d_addrans(x,SIZE,lb,ub)
#else
      call r_init_addrans()
      call r_addrans(x,SIZE,lb,ub)
#endif

c

c ¥¯¥í¥Ã¥¯³«»Ï

call dtime(tarray)

u1 = tarray(1)

c

c »Ø¿ô¤ò·×»»

do 16 i=1,SIZE

y = exp(x(i))

16 continue

c

c ·Ð²á»þ´Ö¤Î¼èÆÀ

call dtime(time)

u2 = tarray(1)

print *,'time used by EXP is ',u2-u1

print *,'last values for x and exp(x) are ',x(SIZE),y

c

call flush(6)

end

Á°µ­¤ÎÎã¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤Ë¤Ï¡¢¥³¥ó¥Ñ¥¤¥é¤¬¼«Æ°Åª¤Ë¥×¥ê¥×¥í¥»¥Ã¥µ¤ò¸Æ¤Ó½Ð¤¹¤è¤¦¤Ë¥½¡¼¥¹¥³¡¼¥É¤òÀÜÈø¼­F (f ¤Ç¤Ï¤Ê¤¤) ¤Î¤Ä¤¤¤¿¥Õ¥¡¥¤¥ë¤ËÆþ¤ì¡¢¥³¥Þ¥ó¥É¹Ô¤Ç-DSP ¤Þ¤¿¤Ï-DDP ¤ò»ØÄꤷ¤ÆÃ±ÀºÅÙ¤Þ¤¿¤ÏÇÜÀºÅÙ¤òÁªÂò¤·¤Þ¤¹¡£

°Ê²¼¤ÎÎã¤Ç¤Ï¡¢d_addrans ¤ò»ÈÍѤ·¤Æ¡¢¥æ¡¼¥¶¡¼¤¬»ØÄꤷ¤¿ÈϰϤǶѰì¤Ëʬ»¶¤¹¤ëÍð¿ô¥Ç¡¼¥¿¤Î¥Ö¥í¥Ã¥¯¤òȯÀ¸¤µ¤»¤ëÊýË¡¤ò¼¨¤·¤Þ¤¹¡£

/*
 * sin ¤Ø¤Î SIZE*LOOPS Íð¿ô°ú¿ô¤ò¥Æ¥¹¥È¤·¤Þ¤¹¡£
 * ÈÏ°Ï¤Ï [0¡¢¤·¤­¤¤ÃÍ ] ¤È¤·¡¢
 * ¤·¤­¤¤ÃÍ = 3E30000000000000 (3.72529029846191406e-09) ¤È¤·¤Þ¤¹¡£
 */
#include <math.h>
#include <sunmath.h>
#define SIZE 10000
#define LOOPS 100
int main()
{
        double x[SIZE], y[SIZE];
        int    i, j, n;
        double lb, ub;
        union {
                unsignedu[2];
                doubled;
        } upperbound;
        upperbound.u[0] = 0x3e300000;
        upperbound.u[1] = 0x00000000;
        /* Íð¿ô´Ø¿ô¤ò½é´ü²½ */
        d_init_addrans_();
        /* sin ¤Ë¤Ä¤¤¤Æ (SIZE * LOOPS) ¸Ä¤Î°ú¿ô¤ò¥Æ¥¹¥È */
        for (j = 0; j < LOOPS; j++) {
        /*
         * Ťµ SIZE ¤ÎÍð¿ô¤Î¥Ù¥¯¥È¥ë x ¤òÀ¸À®¤·¡¢
         * »°³Ñ´Ø¿ô¤Î´Ø¿ô¤Ø¤ÎÆþÎϤȤ·¤Æ»ÈÍÑ
         */
        n = SIZE;
        ub = upperbound.d;
        lb = 0.0;
        d_addrans_(x, &n, &lb, &ub);
        for (i = 0; i < n; i++)
            y[i] = sin(x[i]);
        /*sin(x) == x ¡©¡¡ x ¤¬¾®¤µ¤¤¾ì¹ç¤Ë¤Ê¤ë */
        for (i = 0; i < n; i++)
            if (x[i] != y[i])
               printf(
               " OOPS: %d  sin(%18.17e)=%18.17e \n",
               i, x[i], y[i]);
        }
        printf(" comparison ended; no differences\n");
        ieee_retrospective_();
        return(0);
}

¼¡¤Î FORTRAN ¤ÎÎã¤Ç¤Ï¡¢IEEE ɸ½à¤¬¿ä¾©¤¹¤ë´Ø¿ô¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¡£

c
c¤³¤Î¥×¥í¥°¥é¥à¤Ç¤Ï¡¢IEEE ¿ä¾©¤Î´Ø¿ô¤Î¤¦¤Á¤Î 5 ¤Ä¤ò FORTRAN ¤«¤é¸Æ¤Ó½Ð¤¹
cÊýË¡¤ò¼¨¤·¤Þ¤¹¡£
c¤¿¤È¤¨¤Ð¡¢y=x*2**n ¤ò¹Ô¤¦¤Ë¤Ï¡¢¥Ï¡¼¥É¥¦¥§¥¢¤Ç¤Ï¿ôÃͤ¬´ð¿ô 2 ¤Çµ­²±¤µ¤ì
c¤ë¤¿¤á¡¢»Ø¿ô¤ò n ¤À¤±¥·¥Õ¥È¤·¤Þ¤¹¡£
cÉâÆ°¾®¿ôÅÀ¤Î±é»»µ¡Ç½¤Ë´Ø¤¹¤ë IEEE µ¬³Ê¤Ç¤Ï¡¢¤³¤ì¤é¤Î´Ø¿ô¤òɬ¿Ü¤Ë¤Ï¤·¤Æ¤¤
c¤Þ¤»¤ó¤¬¡¢IEEE ÉâÆ°¾®¿ôÅÀ´Ä¶­¤Ë¤Ï´Þ¤á¤ë¤³¤È¤ò´«¤á¤Æ¤¤¤Þ¤¹¡£
c
c°Ê²¼¤Î¹àÌܤ⻲¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
c
cieee_functions(3m)
clibm_double(3f)
clibm_single(3f)
c
c¤³¤³¤Ç¤Ï¼¡¤Î 5 ¤Ä¤Î´Ø¿ô¤Ë¤Ä¤¤¤ÆÎã¤ò¼¨¤·¤Þ¤¹¡§
c
cilogb(x): x ¤Î´ð¿ô 2 ¤Ç¤Î¥Ð¥¤¥¢¥¹¤µ¤ì¤Æ¤¤¤Ê¤¤»Ø¿ô¤òÀ°¿ô·Á¼°¤ÇÊÖ¤¹
csignbit(x): 0 ¤Þ¤¿¤Ï 1 ¤ÎÉ乿¥Ó¥Ã¥È¤òÊÖ¤¹
ccopysign(x,y): y ¤ÎÉ乿¥Ó¥Ã¥È¤òÉÕ¤±¤¿ x ¤òÊÖ¤¹
cnextafter(x,y): x ¤«¤é y Êý¸þ¤Ë¼¡¤Ë½Ð¸½¤¹¤ëɽ¸½²Äǽ¤Ê¿ôÃͤòÊÖ¤¹
cscalbn(x,n): x * 2**n
c
c´Ø¿ôÇÜÀºÅÙñÀºÅÙ
c--------------------------------------------------------
cilogb(x)i = id_ilogb(x)i = ir_ilogb(r)
csignbit(x)i = id_signbit(x)i = ir_signbit(r)
ccopysign(x,y)x = d_copysign(x,y)r = r_copysign(r,s)
cnextafter(x,y)z = d_nextafter(x,y)r = r_nextafter(r,s)
cscalbn(x,n)x = d_scalbn(x,n)r = r_scalbn(r,n)
c
program ieee_functions_demo
implicit double precision (d)
implicit real (r)
double precision x, y, z, direction
real r, s, t, r_direction
integer i, scale
print *
print *, 'DOUBLE PRECISION EXAMPLES:'
print *
x = 32.0d0
i = id_ilogb(x)
write(*,1) x, i
 1format(' The base 2 exponent of ', F4.1, ' is ', I2)
x = -5.5d0
y = 12.4d0
z = d_copysign(x,y)
write(*,2) x, y, z
 2    format(F5.1, ' was given the sign of ', F4.1,
     *   ' and is now ', F4.1)
x = -5.5d0
i = id_signbit(x)
print *, 'The sign bit of ', x, ' is ', i
x = d_min_subnormal()
direction = -d_infinity()
y = d_nextafter(x, direction)
write(*,3) x
 3format(' Starting from ', 1PE23.16E3,
     -   ', the next representable number ')
write(*,4) direction, y
 4format('    towards ', F4.1, ' is ', 1PE23.16E3)
x = d_min_subnormal()
direction = 1.0d0
    y = d_nextafter(x, direction)
write(*,3) x
write(*,4) direction, y
x = 2.0d0
scale = 3
y = d_scalbn(x, scale)
write (*,5) x, scale, y
 5format(' Scaling ', F4.1, ' by 2**', I1, ' is ', F4.1)
print *
print *, 'SINGLE PRECISION EXAMPLES:'
print *
r = 32.0
i = ir_ilogb(r)
write (*,1) r, i
r = -5.5
i = ir_signbit(r)
print *, 'The sign bit of ', r, ' is ', i
r = -5.5
s = 12.4
t = r_copysign(r,s)
write (*,2) r, s, t
r = r_min_subnormal()
r_direction = -r_infinity()
s = r_nextafter(r, r_direction)
write(*,3) r
write(*,4) r_direction, s
r = r_min_subnormal()
r_direction = 1.0e0
s = r_nextafter(r, r_direction)
write(*,3) r
write(*,4) r_direction, s
r = 2.0
scale = 3
s = r_scalbn(r, scale)
write (*,5) r, scale, y
print *
end


¤³¤Î¥×¥í¥°¥é¥à¤«¤é¤Î½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

 DOUBLE PRECISION EXAMPLES:
 The base 2 exponent of 32.0 is  5
 -5.5 was given the sign of 12.4 and is now  5.5
 The sign bit of    -5.5000000000000 is   1
 Starting from  4.9406564584124654-324, the next representable
    number towards -Inf is  0.0000000000000000E+000
 Starting from  4.9406564584124654-324, the next representable
    number towards  1.0 is  9.8813129168249309-324
 Scaling  2.0 by 2**3 is 16.0
 SINGLE PRECISION EXAMPLES:
 The base 2 exponent of 32.0 is  5
 The sign bit of    -5.50000 is   1
 -5.5 was given the sign of 12.4 and is now  5.5
 Starting from  1.4012984643248171E-045, the next representable
    number towards -Inf is  0.0000000000000000E+000
 Starting from  1.4012984643248171E-045, the next representable
    number towards  1.0 is  2.8025969286496341E-045
 Scaling  2.0 by 2**3 is 16.0
[ÆüËܸìÌõ]
Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤¬È¯À¸¤·¤Þ¤·¤¿:
ÉÔÀµ³Î¡¢¥¢¥ó¥À¡¼¥Õ¥í¡¼
¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Î ieee_flags

°Ê²¼¤Î C ¥×¥í¥°¥é¥à¤Ç¤Ï¡¢ieee_values(3m) ¤Î´Ø¿ô¤ò¸Æ¤Ó½Ð¤·¤Æ¤¤¤Þ¤¹¡£

#include <math.h>
#include <sunmath.h>
int main()
{
     double x;
     float r;
     x = quiet_nan(0);
     printf("quiet NaN: %.16e = %08x %08x \n",
        x, ((int *) &x)[0], ((int *) &x)[1]);
     x = nextafter(max_subnormal(), 0.0);
     printf("nextafter(max_subnormal,0) = %.16e\n",x);
     printf("                           = %08x %08x\n",
        ((int *) &x)[0], ((int *) &x)[1]);
     r = min_subnormalf();
     printf("single precision min subnormal = %.8e = %08x\n",
     r, ((int *) &r)[0]);
     return 0;
}

¥ê¥ó¥¯¤¹¤ë¤È¤­¤Ë¤Ï¡¢-lsunmath ¤È-lm ¤ÎξÊý¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£

SPARC ¤Ç¤Ï¡¢½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

quiet NaN: NaN = 7fffffff ffffffff
nextafter(max_subnormal,0) = 2.2250738585072004e-308
                           = 000fffff fffffffe
single precision min subnormal = 1.40129846e-45 = 00000001

x86 ¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ï¡Ö¥ê¥È¥ë¥¨¥ó¥Ç¥£¥¢¥ó¡×¤Ç¤¢¤ë¤¿¤á¡¢x86 ¤Ç¤Î½ÐÎϤϾ¯¡¹°Û¤Ê¤ê¤Þ¤¹ (ÇÜÀºÅÙ¿ô¤Î 16 ¿Êɽ¸½¤Ç¾å°Ì¤È²¼°Ì¤Î¥ï¡¼¥É¤¬µÕ¤Ë¤Ê¤ê¤Þ¤¹)¡£

quiet NaN: NaN = ffffffff 7fffffff
nextafter(max_subnormal,0) = 2.2250738585072004e-308
                           = fffffffe 000fffff
single precision min subnormal = 1.40129846e-45 = 00000001

ieee_values ´Ø¿ô¤ò»ÈÍѤ¹¤ë FORTRAN ¥×¥í¥°¥é¥à¤Ç¤Ï¡¢´Ø¿ô¤Î·¿¤òÀë¸À¤¹¤ë¤è¤¦¤ËÃí°Õ¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£

      program print_ieee_values
c
c implicit ʸ¤Ï¡¢f77_floatingpoint ¤Îµ¿»÷ÁȤ߹þ¤ß´Ø¿ô¤¬¡¢
c Àµ¤·¤¤·¿¤ÇÀë¸À¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò³Îǧ¤·¤Þ¤¹¡£
c
      implicit real*16 (q)
      implicit double precision (d)
      implicit real (r)
      real*16 z, zero, one
      double precision x
      real r
c
      zero = 0.0
      one = 1.0
      z = q_nextafter(zero, one)
      x = d_infinity()
      r = r_max_normal()
c
      print *, z
      print *, x
      print *, r
c
      end

SPARC ¤Ç¤Ï¡¢½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

x86 ¤Î FORTRAN ¥³¥ó¥Ñ¥¤¥é¤Ï¡¢real*16 ·¿¤ò¥µ¥Ý¡¼¥È¤·¤Ê¤¤¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£Á°µ­¤ÎÎã¤ò x86 ¤Ç¼Â¹Ô¤¹¤ë¤Ë¤Ï¡¢real*16 ¤ÎÊÑ¿ô¤ª¤è¤Ó´Ø¿ô¤ËÂФ¹¤ë»²¾È¤ò¤¹¤Ù¤Æºï½ü¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£

°Ê²¼¤ÎÎã¤Ï¡¢´Ý¤á¥â¡¼¥É¤ò¥¼¥íÀÚ¤ê¼Î¤Æ¥â¡¼¥É¤ËÀßÄꤹ¤ëÊýË¡¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£

#include <math.h>
#include <sunmath.h>
int main()
{
int             i;
double          x, y;
char           *out_1, *out_2, *dummy;
/* °ìÈÌŪ¤Ê´Ý¤á¤ÎÊý¸þ¤ò¼èÆÀ¤¹¤ë */
i = ieee_flags("get", "direction", "", &out_1);
x = sqrt(.5);
printf("With rounding direction %s, \n", out_1);
printf("sqrt(.5) = 0x%08x 0x%08x = %16.15e\n",
       ((int *) &x)[0], ((int *) &x)[1], x);
/* ´Ý¤áÊý¸þ¤ÎÀßÄê */
if (ieee_flags("set", "direction", "tozero", &dummy) != 0)
printf("Not able to change rounding direction!\n");
i = ieee_flags("get", "direction", "", &out_2);
x = sqrt(.5);
/*
 * printf ¤â¸½ºß¤Î´Ý¤áÊý¸þ¤Ë±Æ¶Á¤ò¼õ¤±¤ë¤¿¤á¡¢
 * printf ¤ÎÁ°¤Ë¸µ¤Î´Ý¤áÊý¸þ¤òÉü¸µ¤¹¤ë
 */
if (ieee_flags("set", "direction", out_1, &dummy) != 0)
printf("Not able to change rounding direction!\n");
printf("\nWith rounding direction %s,\n", out_2);
printf("sqrt(.5) = 0x%08x 0x%08x = %16.15e\n",
       ((int *) &x)[0], ((int *) &x)[1], x);
return 0;
}

SPARC ¤Ç¤Ï¡¢¤³¤Îû¤¤¥×¥í¥°¥é¥à¤Î½ÐÎϤϡ¢¥¼¥íÀÚ¤ê¼Î¤Æ¥â¡¼¥É¤Î¸ú²Ì¤ò¼¨¤·¤Þ¤¹¡£

demo%cc rounding_direction.c -lm
demo%a.out
With rounding direction nearest,
sqrt(.5) = 0x3fe6a09e 0x667f3bcd = 7.071067811865476e-01
With rounding direction tozero,
sqrt(.5) = 0x3fe6a09e 0x667f3bcc = 7.071067811865475e-01
demo%

x86 ¤Ç¤Ï¡¢¤³¤Îû¤¤¥×¥í¥°¥é¥à¤Î½ÐÎϤϡ¢¥¼¥íÀÚ¤ê¼Î¤Æ¥â¡¼¥É¤Î¸ú²Ì¤ò¼¨¤·¤Þ¤¹¡£

demo%cc rounding_direction.c -lm
demo%a.out
With rounding direction nearest,
sqrt(.5) = 0x667f3bcd 0x3fe6a09e = 7.071067811865476e-01
With rounding direction tozero,
sqrt(.5) = 0x667f3bcc 0x3fe6a09e = 7.071067811865475e-01
demo%

FORTRAN ¥×¥í¥°¥é¥à¤Ç¥¼¥íÀÚ¤ê¼Î¤Æ¥â¡¼¥É¤òÀßÄꤷ¤Þ¤¹¡£

program ieee_flags_demo
character*16 out
i = ieee_flags("set", "direction", "tozero", out)
if (i.ne.0) print *, 'not able to set rounding direction'
i = ieee_flags("get", "direction", "", out)
print *, "Rounding direction is: ", out
end

½ÐÎϤϰʲ¼¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

Note: Rounding direction toward zero.
See the Numerical Computation Guide, ieee_flags(3M)
[ÆüËܸìÌõ]
Ãí: ¥¼¥íÊý¸þ¤Ø¤Î´Ý¤á
¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_flags

¼¡¤Ë¡¢C99 ÉâÆ°¾®¿ôÅÀ´Ä¶­´Ø¿ô¤ò¤¤¤¯¤Ä¤«»ÈÍѤ·¤¿Îã¤ò¼¨¤·¤Þ¤¹¡£norm ´Ø¿ô¤Ï¡¢¥¢¥ó¥À¡¼¥Õ¥í¡¼¤È¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¤ò½èÍý¤¹¤ë¤¿¤á¡¢¥Ù¥¯¥È¥ë¤Î¥æ¡¼¥¯¥ê¥Ã¥ÉÀµµ¬·Á¤ò·×»»¤·¡¢C99 ÉâÆ°¾®¿ôÅÀ´Ä¶­´Ø¿ô¤ò»ÈÍѤ·¤Þ¤¹¡£¥á¥¤¥ó¥×¥í¥°¥é¥à¤Ï¡¢Á̵ڿÇÃǽÐÎϤ¬¼¨¤¹¤è¤¦¤Ë¡¢¥¢¥ó¥À¡¼¥Õ¥í¡¼¤È¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¤òȯÀ¸¤µ¤»¤ë¤è¤¦¤Ë¥¹¥±¡¼¥ë¤µ¤ì¤¿¥Ù¥¯¥È¥ë¤ò»ÈÍѤ·¤Æ¤³¤Î´Ø¿ô¤ò¸Æ¤Ó½Ð¤·¤Þ¤¹¡£

#include <stdio.h>
#include <math.h>
#include <sunmath.h>
#include <fenv.h>
/*
 * Á᤹¤®¤ë¥¢¥ó¥À¡¼¥Õ¥í¡¼¤Þ¤¿¤Ï¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¤òÈò¤±¤ë¥Ù¥¯¥È¥ë x ¤Î
 * ¥æ¡¼¥¯¥ê¥Ã¥ÉÀµµ¬·Á¤ò·×»»¤·¤Þ¤¹
*/
double norm(int n, double *x)
{
    fenv_t  env;
    double  s, b, d, t;
    int     i, f;
    /* ´Ä¶­¤òÊݸ¤·¤Æ¥Õ¥é¥°¤ò¥¯¥ê¥¢¤·¡¢Ï¢Â³¤·¤¿Îã³°½èÍý¤ò³ÎΩ¤·¤Þ¤¹ */
    feholdexcept(&env);
    /* ¥É¥Ã¥ÈÀÑ x.x ¤Î·×»»¤ò»î¤ß¤Þ¤¹ */
    d = 1.0; /* ·å°Üư»Ò */
    s = 0.0;
    for (i = 0; i < n; i++)
        s += x[i] * x[i];
    /* ¥¢¥ó¥À¡¼¥Õ¥í¡¼¤Þ¤¿¤Ï¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¤òÄ´¤Ù¤Þ¤¹ */
    f = fetestexcept(FE_UNDERFLOW | FE_OVERFLOW);
    if (f & FE_OVERFLOW) {
        /* ºÇ½é¤Î»î¹Ô¤¬¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¤·¤¿¤é¡¢¥¹¥±¡¼¥ê¥ó¥°¤ò
¾®¤µ¤¯¤·¤Æ¤â¤¦°ìÅټ¹Ԥ·¤Æ¤¯¤À¤µ¤¤ */
        feclearexcept(FE_OVERFLOW);
        b = scalbn(1.0, -640);
        d = 1.0 / b;
        s = 0.0;
        for (i = 0; i < n; i++) {
            t = b * x[i];
            s += t * t;
        }
    }
    else if (f & FE_UNDERFLOW && s < scalbn(1.0, -970)) {
        /* ºÇ½é¤Î»î¹Ô¤¬¥¢¥ó¥À¡¼¥Õ¥í¡¼¤·¤¿¤é¡¢¥¹¥±¡¼¥ê¥ó¥°¤ò
Â礭¤¯¤·¤Æ¤â¤¦°ìÅټ¹Ԥ·¤Æ¤¯¤À¤µ¤¤ */
        b = scalbn(1.0, 1022);
        d = 1.0 / b;
        s = 0.0;
        for (i = 0; i < n; i++) {
            t = b * x[i];
            s += t * t;
        }
    }
    /* ¤³¤ì¤Þ¤Ç¤ËȯÀ¸¤·¤¿¥¢¥ó¥À¡¼¥Õ¥í¡¼¤ò¤¹¤Ù¤Æ±£¤·¤Þ¤¹ */
    feclearexcept(FE_UNDERFLOW);
    /* ´Ä¶­¤òÉü¸µ¤·¡¢¤³¤ì¤Þ¤Ç¤Ëµ¯¤­¤¿¤Û¤«¤ÎÎã³°¤òȯÀ¸¤µ¤»¤Þ¤¹ */
    feupdateenv(&env);
    /* Ê¿Êýº¬¤ò¼èÆÀ¤·¡¢¥¹¥±¡¼¥ê¥ó¥°¤ò²ò½ü¤·¤Þ¤¹ */
    return d * sqrt(s);
}
int main()
{
    double x[100], l, u;
    int    n = 100;
    fex_set_log(stdout);
    l = 0.0;
    u = min_normal();
    d_lcrans_(x, &n, &l, &u);
    printf("norm: %g\n", norm(n, x));
    l = sqrt(max_normal());
    u = l * 2.0;
    d_lcrans_(x, &n, &l, &u);
    printf("norm: %g\n", norm(n, x));
    return 0;
}


SPARC ¤Ç¤³¤Î¥×¥í¥°¥é¥à¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤Æ¼Â¹Ô¤¹¤ë¤È¡¢¼¡¤Î¤è¤¦¤Ë½ÐÎϤµ¤ì¤Þ¤¹¡£

demo%cc norm.c -R/opt/SUNWspro/lib -L/opt/SUNWspro/lib -lm9x
-lsunmath -lm
demo%a.out
Floating point underflow at 0x000153a8 __d_lcrans_, nonstop mode
  0x000153b4  __d_lcrans_
  0x00011594  main
Floating point underflow at 0x00011244 norm, nonstop mode
  0x00011248  norm
  0x000115b4  main
norm: 1.32533e-307
Floating point overflow at 0x00011244 norm, nonstop mode
  0x00011248  norm
  0x00011660  main
norm: 2.02548e+155

¼¡¤ÎÎã¤Ï¡¢x86 ¤Ç¤Îfesetprec ´Ø¿ô¤Î·ë²Ì¤ò¼¨¤·¤Æ¤¤¤Þ¤¹ (¤³¤Î´Ø¿ô¤Ï SPARC ¤Ç¤Ï»ÈÍѤǤ­¤Þ¤»¤ó)¡£while ¥ë¡¼¥×¤Ï¡¢1 ¤Ë²Ã¤¨¤é¤ì¤ë¤È¤­¤Ë´°Á´¤Ë´Ý¤á¤é¤ì¤ë¡¢2 ¤ÎºÇÂç¤ÎÎß¾è¤òõ¤¹¤³¤È¤Ë¤è¤ê¡¢»ÈÍѤǤ­¤ëÀºÅ٤ηèÄê¤ò»î¤ß¤Æ¤¤¤Þ¤¹¡£ºÇ½é¤Î¥ë¡¼¥×¤¬¼¨¤¹¤è¤¦¤Ë¡¢¤¹¤Ù¤Æ¤ÎÃæ´Ö·ë²Ì¤ò³ÈÄ¥ÇÜÀºÅÙ¤Çɾ²Á¤¹¤ë x86 ¤Î¤è¤¦¤Ê¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç¤Ï¡¢¤³¤Î¼êË¡¤¬´üÂԤɤª¤ê¤Ëưºî¤·¤Ê¤¤¾ì¹ç¤¬¤¢¤ê¤Þ¤¹¡£¤½¤Î¤¿¤á¡¢2 ÈÖÌܤΥ롼¥×¤¬¼¨¤¹¤è¤¦¤Ë¡¢fesetprec ´Ø¿ô¤ò»ÈÍѤ·¤Æ¡¢¤¹¤Ù¤Æ¤Î·ë²Ì¤¬´õ˾¤¹¤ëÀºÅ٤˴ݤá¤é¤ì¤ë¤è¤¦¤Ë»ØÄê¤Ç¤­¤Þ¤¹¡£

#include <math.h>
#include <fenv.h>
int main()
{
    double  x;
    x = 1.0;
    while (1.0 + x != 1.0)
        x *= 0.5;
    printf("%d significant bits\n", -ilogb(x));
    fesetprec(FE_DBLPREC);
    x = 1.0;
    while (1.0 + x != 1.0)
        x *= 0.5;
    printf("%d significant bits\n", -ilogb(x));
    return 0;
}


x86 ¥·¥¹¥Æ¥à¤Ç¤Ï¡¢¤³¤Î¥×¥í¥°¥é¥à¤Î½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

64 significant bits
53 significant bits

¼¡¤Î¥³¡¼¥É¥Õ¥é¥°¥á¥ó¥È¤Ï¡¢¥Þ¥ë¥Á¥¹¥ì¥Ã¥ÉÂбþ¤Î¥×¥í¥°¥é¥à¤Ç´Ä¶­´Ø¿ô¤ò»ÈÍѤ·¤Æ¡¢¿Æ¥¹¥ì¥Ã¥É¤«¤é»Ò¥¹¥ì¥Ã¥É¤ËÉâÆ°¾®¿ôÅÀ¥â¡¼¥É¤òÅÁ¤¨¡¢»Ò¥¹¥ì¥Ã¥É¤¬¿Æ¥¹¥ì¥Ã¥É¤Ë·ë¹ç¤µ¤ì¤ë¤È¤­¤Ë»Ò¥¹¥ì¥Ã¥ÉÆâ¤ÇȯÀ¸¤¹¤ëÎã³°¥Õ¥é¥°¤ò²óÉü¤¹¤ëÊýË¡¤ò¼¨¤·¤Æ¤¤¤Þ¤¹ (¥Þ¥ë¥Á¥¹¥ì¥Ã¥ÉÂбþ¤Î¥×¥í¥°¥é¥à¤Îµ­½Ò¤Ë¤Ä¤¤¤Æ¤Ï¡¢¡ØSolaris ¤Ç¤Î¥Þ¥ë¥Á¥¹¥ì¥Ã¥É¤Î¥×¥í¥°¥é¥ß¥ó¥°¡Ù¤ò»²¾È)¡£

#include <thread.h>
#include <fenv.h>
fenv_t  env;
void child(void *p)
{
    /* Æþ¸ý¤Ç¿Æ¤Î´Ä¶­¤ò·Ñ¾µ¤·¤Þ¤¹ */
    fesetenv(&env);
    ...
    /* ½ªÎ»Á°¤Ë»Ò¤Î´Ä¶­¤òÊݸ¤·¤Þ¤¹ */
    fegetenv(&env);
}
void parent()
{
    thread_t tid;
    void *arg;
    ...
    /* »Ò¤òºîÀ®¤¹¤ëÁ°¤Ë¿Æ¤Î´Ä¶­¤òÊݸ¤·¤Þ¤¹ */
    fegetenv(&env);
    thr_create(NULL, NULL, child, arg, NULL, &tid);
    ...
    /* »Ò¤È·ë¹ç¤·¤Þ¤¹ */
    thr_join(tid, NULL, &arg);
    /* »Ò¤ÇȯÀ¸¤·¤¿Îã³°¥Õ¥é¥°¤ò¿Æ¤Î´Ä¶­¤Ë¥Þ¡¼¥¸¤·¤Þ¤¹ */
    fex_merge_flags(&env);
    ...
}


°ìÈÌŪ¤Ë¤Ï¡¢Îã³°¥Ó¥Ã¥È¤Î¸¡¾Ú¤ä¥¯¥ê¥¢¤Ï¥æ¡¼¥¶¡¼¥×¥í¥°¥é¥à¤Ç¹Ô¤¤¤Þ¤¹¡£¼«Á³È¯À¸¤·¤¿Îã³°¥Õ¥é¥°¤ò¸¡¾Ú¤¹¤ë C ¥×¥í¥°¥é¥à¤ò¼¨¤·¤Þ¤¹¡£

#include <sunmath.h>
#include <sys/ieeefp.h>
int main()
{
int code, inexact, division, underflow, overflow, invalid;
double x;
char *out;
/* ¥¢¥ó¥À¡¼¥Õ¥í¡¼Îã³°¤òȯÀ¸¤µ¤»¤ë */
x = max_subnormal() / 2.0;
/* ¤³¤Îʸ¤Ï¡¢Á°¤Îʸ¤¬ºÇŬ²½¤µ¤ì¤Æ¤¤¤Ê¤¤¤³¤È¤ò¼¨¤¹ */
printf("x = %g\n",x);
/* ¤É¤ÎÎã³°¤¬È¯À¸¤·¤¿¤«¤òȽÄꤹ¤ë */
code = ieee_flags("get", "exception", "", &out);
/* Ìá¤êÃͤò²òÆÉ¤¹¤ë */
inexact =      (code >> fp_inexact)     & 0x1;
underflow =    (code >> fp_underflow)   & 0x1;
division =     (code >> fp_division)    & 0x1;
overflow =     (code >> fp_overflow)    & 0x1;
invalid =      (code >> fp_invalid)     & 0x1;
/* "out" ¤ÏȯÀ¸¤·¤¿Îã³°¤Î¤¦¤Á¤ÇºÇ¤âÍ¥ÀèÅÙ¤¬¹â¤¤ */
 printf(" Highest priority exception is: %s\n", out);
 /* 1 ¤ÏÎã³°¤¬È¯À¸¤·¤¿¤³¤È¤ò¼¨¤·¡¢ */
 /* 0 ¤ÏÎã³°¤¬È¯À¸¤·¤Æ¤¤¤Ê¤¤¤³¤È¤ò¼¨¤¹ */
 printf("%d %d %d %d %d\n", invalid, overflow, division,
 underflow, inexact);
     ieee_retrospective_();
 return(0);
}

¤³¤Î¥×¥í¥°¥é¥à¤ò¼Â¹Ô¤·¤¿·ë²Ì¤Î½ÐÎϤǤ¹¡£

demo%a.out
x = 1.11254e-308
 Highest priority exception is: underflow
0 0 0 1 1
    Inexact;  Underflow;
 See the Numerical Computation Guide, ieee_flags(3M)
[ÆüËܸìÌõ]
Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤¬È¯À¸¤·¤Þ¤·¤¿:
ÉÔÀµ³Î¡¢¥¢¥ó¥À¡¼¥Õ¥í¡¼
¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_flags

FORTRAN ¤Ç¤âƱ¤¸¤³¤È¤¬¹Ô¤¨¤Þ¤¹¡£

/*
¤³¤ì¤Ï¡¢¼¡¤Î¤è¤¦¤ÊFORTRAN ¥×¥í¥°¥é¥àÎ㠤Ǥ¹¡§
*  ¥¢¥ó¥À¡¼¥Õ¥í¡¼Îã³°¤òȯÀ¸¤µ¤»¤ë
*ieee_flags ¤ò»ÈÍѤ·¤Æ¡¢¤É¤ÎÎã³°¤¬È¯À¸¤·¤¿¤«¤òȽÄꤹ¤ë
*ieee_flags ¤¬ÊÖ¤¹À°¿ôÃͤò²òÆÉ¤¹¤ë
* ̤½èÍý¤ÎÎã³°¤ò¤¹¤Ù¤Æ¥¯¥ê¥¢¤Ë¤¹¤ë
C ¤Î¥×¥ê¥×¥í¥»¥Ã¥µ¤¬µ¯Æ°¤µ¤ì¡¢¥Ø¥Ã¥À¡¼¥Õ¥¡¥¤¥ëf77_floatingpoint.h ¤¬¼è¤ê¹þ¤Þ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¡¢¤³¤Î¥×¥í¥°¥é¥à¤ÏÀÜÈø¼­.F ¤Î¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Æ¤¯¤À¤µ¤¤¡£
*/
#include <f77_floatingpoint.h>
      program decode_accrued_exceptions
      double precision x
      integer accrued, inx, div, under, over, inv
      character*16 out
      double precision d_max_subnormal
c ¥¢¥ó¥À¡¼¥Õ¥í¡¼Îã³°¤òȯÀ¸¤µ¤»¤ë
      x = d_max_subnormal() / 2.0
c ¤É¤ÎÎã³°¤¬È¯À¸¤·¤¿¤«¤òȽÄꤹ¤ë
      accrued = ieee_flags('get', 'exception', '', out)
c ¥Ó¥Ã¥È¥·¥Õ¥È¤ÎÁȤ߹þ¤ß¤ò»ÈÍѤ·¤Æ¡¢ieee_flags ¤¬ÊÖ¤·¤¿Ãͤò²òÆÉ¤¹¤ë
      inx   = and(rshift(accrued, fp_inexact)  , 1)
      under = and(rshift(accrued, fp_underflow), 1)
      div   = and(rshift(accrued, fp_division) , 1)
      over  = and(rshift(accrued, fp_overflow) , 1)
      inv   = and(rshift(accrued, fp_invalid)  , 1)
c ºÇ¹â¤ÎÍ¥ÀèÅÙ¤ò¤â¤ÄÎã³°¤¬ "out" ¤ËÊÖ¤µ¤ì¤ë
      print *, "Highest priority exception is ", out
c1 ¤ÏÎã³°¤¬È¯À¸¤·¤¿¤³¤È¤ò¼¨¤·¡¢0 ¤ÏÎã³°¤¬È¯À¸¤·¤Æ¤¤¤Ê¤¤¤³¤È¤ò¼¨¤¹
      print *, inv, over, div, under, inx
c ̤½èÍý¤ÎÎã³°¤ò¤¹¤Ù¤Æ¥¯¥ê¥¢¤Ë¤¹¤ë
      i = ieee_flags('clear', 'exception', 'all', out)
      end

¤³¤Î FORTRAN ¥×¥í¥°¥é¥à¤Î½ÐÎϤǤ¹¡£

 Highest priority exception is underflow
   0  0  0  1  1

Ä̾¥æ¡¼¥¶¡¼¥×¥í¥°¥é¥à¤ÇÎã³°¥Õ¥é¥°¤òÀßÄꤹ¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢¤Ç¤­¤Ê¤¤¤³¤È¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£°Ê²¼¤Î C ¤ÎÎã¤Ç¤½¤ì¤ò¼¨¤·¤Þ¤¹¡£

#include <sunmath.h>
int main()
{
int             code;
char           *out;
if (ieee_flags("clear", "exception", "all", &out) != 0)
   printf("could not clear exceptions\n");
if (ieee_flags("set", "exception", "division", &out) != 0)
   printf("could not get exception\n");
code = ieee_flags("get", "exception", "", &out);
printf("out is: %s , fp exception code is: %X \n",
    out, code);
return(0);
}

SPARC ¤Ç¤Ï¡¢Á°µ­¤Î¥×¥í¥°¥é¥à¤Î½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

out is: division , fp exception code is: 2

x86 ¤Ç¤Ï¡¢½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

out is: division , fp exception code is: 4


Ãí -°Ê²¼¤ÎÎã¤Ï¡¢Solaris ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°´Ä¶­¤À¤±¤ËŬÍѤǤ­¤Þ¤¹¡£

SPARC ¤Ç¤Ï¡¢Îã³°¤òÆÃÄꤹ¤ë¤¿¤á¤Î¥·¥°¥Ê¥ë¥Ï¥ó¥É¥é¤òÀßÄꤹ¤ë FORTRAN ¤ª¤è¤Ó C ¥×¥í¥°¥é¥à¤ÎÎã¤ò¼¨¤·¤Þ¤¹¡£

FORTRAN ¥×¥í¥°¥é¥àÎã

      program demo
c ¥·¥°¥Ê¥ë¥Ï¥ó¥É¥é´Ø¿ô¤ÎÀë¸À
      external fp_exc_hdl
      double precision d_min_normal
      double precision x
c ¥·¥°¥Ê¥ë¥Ï¥ó¥É¥é¤ÎÀßÄê
      i = ieee_handler(`set', `common', fp_exc_hdl)
      if (i.ne.0) print *, `ieee trapping not supported here'
c ¥¢¥ó¥À¡¼¥Õ¥í¡¼Îã³°¤òȯÀ¸¤µ¤»¤ë (¥È¥é¥Ã¥×¤Ï¤µ¤ì¤Ê¤¤)
      x = d_min_normal() / 13.0
      print *, `d_min_normal() / 13.0 = `, x
c ¥ª¡¼¥Ð¡¼¥Õ¥í¡¼Îã³°¤òȯÀ¸¤µ¤»¤ë
c ½ÐÎϤµ¤ì¤¿ÃͤϷë²Ì¤È¤Ï´Ø·¸¤Ê¤¤
      x = 1.0d300*1.0d300
      print *, `1.0d300*1.0d300 = `, x
      end
c
c ÉâÆ°¾®¿ôÅÀÎã³°½èÍý´Ø¿ô
c
      integer function fp_exc_hdl(sig, sip, uap)
      integer sig, code, addr
      character label*16
c
c ¹½Â¤ÂÎ /siginfo/ ¤Ï <sys/siginfo.h> ¤Ë¤è¤ë siginfo_t ¤Î²ò¼á
c
      structure /fault/
      integer address
      end structure
      structure /siginfo/
      integer si_signo
      integer si_code
      integer si_errno
      record /fault/ fault
      end structure
      record /siginfo/ sip
c FPE ¥³¡¼¥É¤Î°ìÍ÷¤Ï <sys/machsig.h> ¤ò»²¾È
c SIGFPE ̾¤ò¸¡½Ð
      code = sip.si_code
      if (code.eq.3) label = 'division'
      if (code.eq.4) label = 'overflow'
      if (code.eq.5) label = 'underflow'
      if (code.eq.6) label = 'inexact'
      if (code.eq.7) label = 'invalid'
      addr = sip.fault.address
c ȯÀ¸¤·¤¿¥·¥°¥Ê¥ë¤Ë´Ø¤¹¤ë¾ðÊó¤ò½ÐÎÏ
      write (*,77) code, label, addr
 77   format ('floating-point exception code ', i2, ',',
     *       a17, ',', ' at address ', z8 )
      end


½ÐÎϤϼ¡¤Î¤È¤ª¤ê¤Ç¤¹¡£

  d_min_normal() / 13.0 =     1.7115952757748-309
floating-point exception code  4, overflow        , at address    1131C
 1.0d300*1.0d300 =     1.0000000000000+300
    Inexact;  Underflow;
 IEEE floating-point exception traps enabled:
    overflow; division by zero; invalid operation;
[ÆüËܸìÌõ]
Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤¬È¯À¸¤·¤Þ¤·¤¿:
ÉÔÀµ³Î¡¢¥¢¥ó¥À¡¼¥Õ¥í¡¼
°Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤Î¥È¥é¥Ã¥×¤¬Í­¸ú¤Ç¤¹:
¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¡¢¥¼¥í¤Ë¤è¤ë½ü»»¡¢Ìµ¸ú¤Ê±é»»
¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_flagsieee_handler

C ¥×¥í¥°¥é¥àÎã

/*
 * 5 ¤Ä¤Î IEEE Îã³° (̵¸ú¤Ê±é»»¡¢¥¼¥í½ü»»¡¢¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¡¢
 * ¥¢¥ó¥À¡¼¥Õ¥í¡¼¡¢ÉÔÀµ³Î·ë²Ì) ¤òȯÀ¸¤µ¤»¤Þ¤¹¡£
 * ¤¹¤Ù¤Æ¤ÎÉâÆ°¾®¿ôÅÀÎã³°¤ò¥È¥é¥Ã¥×¤·¡¢
 * ¥á¥Ã¥»¡¼¥¸¤ò½ÐÎϤ·¤Æ¤«¤é½èÍý¤ò³¤±¤Þ¤¹¡£
 *    i = ieee("get","exception","",&out);
 * ¾åµ­¤Î¼°¤Ë¤è¤Ã¤ÆÈ¯À¸¤·¤¿Îã³°¤Ë¤Ä¤¤¤ÆÌ䤤¹ç¤ï¤»¤ò¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¹¡£
 * ȯÀ¸¤·¤¿ºÇ¹â¤ÎÎ㳰̾¤¬´Þ¤Þ¤ì¡¢i ¤Ï¤¹¤Ù¤Æ¤ÎÎã³°¤ò¸¡½Ð¤¹¤ë¤è¤¦¤Ë
 * ²ò¼á¤µ¤ì¤Þ¤¹¡£
 */
#include <sunmath.h>
#include <signal.h>
#include <siginfo.h>
#include <ucontext.h>
extern void trap_all_fp_exc(int sig, siginfo_t *sip,
ucontext_t *uap);
int main()
{
doublex, y, z;
char*out;
/*
 * Use ieee_handler to establish "trap_all_fp_exc"
 * as the signal handler to use whenever any floating
 * point exception occurs.
 */
if (ieee_handler("set", "all", trap_all_fp_exc) != 0)
printf(" IEEE trapping not supported here.\n");
/* disable trapping (uninteresting) inexact exceptions */
if (ieee_handler("set", "inexact", SIGFPE_IGNORE) != 0)
printf("Trap handler for inexact not cleared.\n");
/* raise invalid */
if (ieee_flags("clear", "exception", "all", &out) != 0)
printf(" could not clear exceptions\n");
printf("1. Invalid: signaling_nan(0) * 2.5\n");
x = signaling_nan(0);
y = 2.5;
z = x * y;
/* raise division */
if (ieee_flags("clear", "exception", "all", &out) != 0)
printf(" could not clear exceptions\n");
printf("2. Div0: 1.0 / 0.0\n");
x = 1.0;
y = 0.0;
z = x / y;
/* raise overflow */
if (ieee_flags("clear", "exception", "all", &out) != 0)
printf(" could not clear exceptions\n");
printf("3. Overflow: -max_normal() - 1.0e294\n");
x = -max_normal();
y = -1.0e294;
z = x + y;
/* raise underflow */
if (ieee_flags("clear", "exception", "all", &out) != 0)
printf(" could not clear exceptions\n");
printf("4. Underflow: min_normal() * min_normal()\n");
x = min_normal();
y = x;
z = x * y;
/* enable trapping on inexact exception */
if (ieee_handler("set", "inexact", trap_all_fp_exc) != 0)
printf("Could not set trap handler for inexact.\n");
/* raise inexact */
if (ieee_flags("clear", "exception", "all", &out) != 0)
printf(" could not clear exceptions\n");
printf("5. Inexact: 2.0 / 3.0\n");
x = 2.0;
y = 3.0;
z = x / y;
/* don't trap on inexact */
if (ieee_handler("set", "inexact", SIGFPE_IGNORE) != 0)
printf(" could not reset inexact trap\n");
/* check that we're not trapping on inexact anymore */
if (ieee_flags("clear", "exception", "all", &out) != 0)
printf(" could not clear exceptions\n");
printf("6. Inexact trapping disabled; 2.0 / 3.0\n");
x = 2.0;
y = 3.0;
z = x / y;
/* find out if there are any outstanding exceptions */
ieee_retrospective_();
/* exit gracefully */
return 0;
}
void trap_all_fp_exc(int sig, siginfo_t *sip, ucontext_t *uap) {
char*label = "undefined";
/* see /usr/include/sys/machsig.h for SIGFPE codes */
switch (sip->si_code) {
case FPE_FLTRES:
label = "inexact";
break;
case FPE_FLTDIV:
label = "division";
break;
case FPE_FLTUND:
label = "underflow";
break;
case FPE_FLTINV:
label = "invalid";
break;
case FPE_FLTOVF:
label = "overflow";
break;
}
printf(
" signal %d, sigfpe code %d: %s exception at address %x\n",
sig, sip->si_code, label, sip->_data._fault._addr);
}


¤³¤Î C ¥×¥í¥°¥é¥à¤Î·ë²Ì¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

1. Invalid: signaling_nan(0) * 2.5
   signal 8, sigfpe code 7: invalid exception at address 10da8
2. Div0: 1.0 / 0.0
   signal 8, sigfpe code 3: division exception at address 10e44
3. Overflow: -max_normal() - 1.0e294
   signal 8, sigfpe code 4: overflow exception at address 10ee8
4. Underflow: min_normal() * min_normal()
   signal 8, sigfpe code 5: underflow exception at address 10f80
5. Inexact: 2.0 / 3.0
   signal 8, sigfpe code 6: inexact exception at address 1106c
6. Inexact trapping disabled; 2.0 / 3.0
Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤¬È¯À¸¤·¤Þ¤·¤¿:
ÉÔÀµ³Î¡¢¥¢¥ó¥À¡¼¥Õ¥í¡¼
°Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤Î¥È¥é¥Ã¥×¤¬Í­¸ú¤Ç¤¹:
¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¡¢¥¼¥í¤Ë¤è¤ë½ü»»¡¢Ìµ¸ú¤Ê±é»»
¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_flagsieee_handler

SPARC ¤Ç¤Ï¡¢¼¡¤Î¥×¥í¥°¥é¥à¤Ï¡¢¤¢¤ëÎã³°¤Î¾õ¶·¤«¤éµ¯¤­¤¿¥Ç¥Õ¥©¥ë¥È·ë²Ì¤ò½¤Àµ¤¹¤ë¤¿¤á¤Îieee_handler ¤È¥¤¥ó¥¯¥ë¡¼¥É¥Õ¥¡¥¤¥ë¤Î»ÈÍÑÊýË¡¤ò¼¨¤·¤Æ¤¤¤Þ¤¹¡£

/*
 * ¥¼¥í½ü»»¤ÎÎã³°¤òȯÀ¸¤µ¤»¡¢¥·¥°¥Ê¥ë¥Ï¥ó¥É¥é¤ò»ÈÍѤ·¤Æ·ë²Ì¤ò MAXDOUBLE
 * (¤Þ¤¿¤Ï MAXFLOAT) ¤ÇÃÖ¤­´¹¤¨¤Þ¤¹¡£
 *
 * ¥Õ¥é¥° -Xa ¤Ç¥³¥ó¥Ñ¥¤¥ë¤·¤Þ¤¹¡£
 */
#include <values.h>
#include <siginfo.h>
#include <ucontext.h>
void division_handler(int sig, siginfo_t *sip, ucontext_t *uap);
int main() {
doublex, y, z;
floatr, s, t;
char*out;
/*
 * ieee_handler ¤ò»ÈÍѤ·¡¢division_handler ¤ò IEEE Îã³°
 * "division" ¤¬È¯À¸¤·¤¿¤È¤­¤Ë»ÈÍѤ¹¤ë¥·¥°¥Ê¥ë¥Ï¥ó¥É¥é¤ËÀßÄꤹ¤ë
 */
if (ieee_handler("set","division",division_handler)!=0) {
printf(" IEEE trapping not supported here.\n");
}
/* ¥¼¥í½ü»»¤ÎÎã³°¤òȯÀ¸¤µ¤»¤ë */
x = 1.0;
y = 0.0;
z = x / y;
/*
 * ¥æ¡¼¥¶¡¼¤¬Ä󶡤·¤¿ÃÍ MAXDOUBLE ¤¬ IEEE ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ë
 * ̵¸ÂÂç¤ÎÂå¤ï¤ê¤ËÃÖ´¹¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò³Îǧ¤¹¤ë
 */
printf("double precision division: %g/%g = %g \n",x,y,z);
/* ¥¼¥í½ü»»¤ÎÎã³°¤òȯÀ¸¤µ¤»¤ë */
r = 1.0;
s = 0.0;
t = r / s;
/*
 * ¥æ¡¼¥¶¡¼¤¬Ä󶡤·¤¿ÃÍ MAXFLOAT ¤¬ IEEE ¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤǤ¢¤ë
 * ̵¸ÂÂç¤ÎÂå¤ï¤ê¤ËÃÖ´¹¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò³Îǧ¤¹¤ë
 */
printf("single precision division: %g/%g = %g \n",r,s,t);
ieee_retrospective_();
return 0;
}
void division_handler(int sig, siginfo_t *sip, ucontext_t *uap) {
intinst;
unsignedrd, mask, single_prec=0;
floatf_val = MAXFLOAT;
doubled_val = MAXDOUBLE;
long*f_val_p = (long *) &f_val;
/* Îã³°¤òȯÀ¸¤µ¤»¤ëÌ¿Îá */
inst = uap->uc_mcontext.fpregs.fpu_q->FQu.fpq.fpq_instr;
/*
 * °ÜưÀè¤Î¥ì¥¸¥¹¥¿¤òÉü¹æ²½¤¹¤ë¡£
 * ¥Ó¥Ã¥È 29:25 ¤Ï¡¢SPARC ÉâÆ°¾®¿ôÅÀÌ¿Îá¤ËÂФ·¤Æ
 * °ÜưÀè¥ì¥¸¥¹¥¿¤òÉ乿²½¤¹¤ë
 */
mask = 0x1f;
rd = (mask & (inst >> 25));
/*
 * ¤³¤ì¤ÏñÀºÅÙÌ¿ÎᤫÇÜÀºÅÙÌ¿Îᤫ?
 * ¥Ó¥Ã¥È 5:6 ¤Ï opcode ¤ÎÀºÅÙ¤òÉ乿²½¤¹¤ë¡£
 * ¥Ó¥Ã¥È 5 ¤¬ 1 ¤Ç¤¢¤ì¤Ð sp ¤È¤Ê¤ê¡¢¤½¤ì°Ê³°¤Ï dp ¤È¤Ê¤ë
 */
mask = 0x1;
single_prec = (mask & (inst >> 5));
/* ¥æ¡¼¥¶¡¼¤¬ÄêµÁ¤·¤¿Ãͤò°ÜưÀè¥ì¥¸¥¹¥¿¤ËÆþ¤ì¤ë */
if (single_prec) {
uap->uc_mcontext.fpregs.fpu_fr.fpu_regs[rd] =
f_val_p[0];
} else {
uap->uc_mcontext.fpregs.fpu_fr.fpu_dregs[rd/2] = d_val;
}
}


´üÂÔ¤µ¤ì¤ë½ÐÎϤϼ¡¤Î¤È¤ª¤ê¤Ç¤¹¡£

double precision division: 1/0 = 1.79769e+308
single precision division: 1/0 = 3.40282e+38
   division by zero;
See the Numerical Computation Guide, ieee_handler(3M)
[ÆüËܸìÌõ]
Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤Î¥È¥é¥Ã¥×¤¬Í­¸ú¤Ç¤¹:
¥¼¥í¤Ë¤è¤ë½ü»»
¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_handler

ÆÃÄê¤ÎÉâÆ°¾®¿ôÅÀÎã³°¤Î¾ì¹ç¡¢ieee_handler ¤ò»ÈÍѤ·¤Æ¶¯À©Åª¤Ë¥×¥í¥°¥é¥à¤ò°Û¾ï½ªÎ»¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

#include <f77_floatingpoint.h>
      program abort
c
      ieeer = ieee_handler('set', 'division', SIGFPE_ABORT)
      if (ieeer .ne. 0) print *, ' ieee trapping not supported'
      r = 14.2
      s = 0.0
      r = r/s
c
      print *, 'you should not see this; system should abort'
c
      end

¤³¤ÎÀá¤Ç¤Ï¡¢libm9x.so ¤¬Ä󶡤¹¤ëÎã³°½èÍýµ¡Ç½¤Î°ìÉô¤Î»ÈÍÑÊýË¡¤ò¼¨¤·¤¿Îã¤ò¼è¤ê¤¢¤²¤Þ¤¹¡£ºÇ½é¤ÎÎã¤Ï¡¢¿ôÃÍx ¤È·¸¿ôa0¡¢a1¡¢...aN¡¢¤ª¤è¤Ób0¡¢b1¡¢....bN-1 ¤Î¾ì¹ç¤Ë¡¢´Ø¿ôf(x) ¤È¤½¤ÎºÇ½é¤ÎƳ´Ø¿ôf'(x) ¤òɾ²Á¤¹¤ë¥¿¥¹¥¯¤Ë´ð¤Å¤¤¤Æ¤¤¤Þ¤¹¡£¤³¤Î¾ì¹çf ¤ÏϢʬ¿ôf(x) =a0 +b0/(x +a1 +b1/(x + ... /(x +aN-1 +bN-1/(x +aN))...))¤Ç¤¹¡£IEEE ±é»»¤Ç¤Ï¡¢f ¤Î·×»»¤Ï´Êñ¤Ç¤¹¡£Ãæ´Ö½ü»»¤Î 1 ¤Ä¤¬¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¤·¤¿¤ê¥¼¥í½ü»»¤ò¹Ô¤¦¾ì¹ç¤Ç¤â¡¢É¸½à¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤¿¥Ç¥Õ¥©¥ë¥È¤ÎÃÍ (Àµ¤·¤¯É乿¤¬ÉÕ¤¤¤¿Ìµ¸ÂÂç) ¤¬Àµ¤·¤¤·ë²Ì¤ò½Ð¤·¤Þ¤¹¡£°ìÊý¡¢f' ¤Î·×»»¤Ï¡¢¤³¤ì¤òɾ²Á¤¹¤ë¤â¤Ã¤È¤â´Ê·é¤Ê¥Õ¥©¡¼¥à¤¬¡¢ºï½ü²Äǽ¤ÊÆÃ°ÛÅÀ¤ò»ý¤Æ¤ë¤¿¤á¡¢f ¤Î·×»»¤è¤ê¤âº¤Æñ¤Ç¤¹¡£·×»»Ãæ¤Ë¤³¤ì¤é¤ÎÆÃ°ÛÅÀ¤Î 1 ¤Ä¤¬½Ð¸½¤¹¤ë¤È¡¢ÉÔÄê·Á 0/0¡¢0*̵¸ÂÂ硢̵¸ÂÂç/̵¸ÂÂç¤Î 1 ¤Ä¤Îɾ²Á¤¬»î¤ß¤é¤ì¤Þ¤¹ (¤³¤ì¤é¤ÎÉÔÄê·Á¤Ï¤¹¤Ù¤ÆÌµ¸ú¤Ê±é»»Îã³°¤òȯÀ¸¤·¤Þ¤¹)¡£W. Kahan ¤Ï¡¢¡ÖÁ°ÃÖ´¹¡×¤È¤¤¤¦µ¡Ç½¤Ë¤è¤ê¤³¤ì¤é¤ÎÎã³°¤ò½èÍý¤¹¤ëÊýË¡¤òÄ󾧤·¤Æ¤¤¤Þ¤¹¡£

Á°ÃÖ´¹¤Ï¡¢Îã³°¤ËÂФ¹¤ë IEEE ¤Î¥Ç¥Õ¥©¥ë¥È¤Î±þÅú (Îã³°±é»»¤Î·ë²Ì¤òÃÖ´¹¤¹¤ëÃͤò¥æ¡¼¥¶¡¼¤¬Á°¤â¤Ã¤Æ»ØÄꤹ¤ë¤³¤È¤òµö²Ä¤¹¤ë) ¤ò³ÈÄ¥¤·¤¿¤â¤Î¤Ç¤¹¡£libm9x.so ¤ò»ÈÍѤ¹¤ë¤È¡¢FEX_CUSTOM Îã³°½èÍý¥â¡¼¥É¤Ç¥Ï¥ó¥É¥é¤ò¥¤¥ó¥¹¥È¡¼¥ë¤·¡¢¥×¥í¥°¥é¥à¤Ç´Êñ¤ËÁ°ÃÖ´¹¤ò¼ÂÁõ¤Ç¤­¤Þ¤¹¡£¤³¤Î¥â¡¼¥É¤Ç¤Ï¡¢¥Ï¥ó¥É¥é¤ËÅϤµ¤ì¤¿info ¥Ñ¥é¥á¡¼¥¿¤¬¼¨¤¹¥Ç¡¼¥¿¹½Â¤¤ËÃͤò³ÊǼ¤¹¤ë¤À¤±¤Ç¡¢¥Ï¥ó¥É¥é¤ÏÎã³°±é»»¤Î·ë²Ì¤ËÂФ·¤ÆÇ¤°Õ¤ÎÃͤò¶¡µë¤Ç¤­¤Þ¤¹¡£¼¡¤Ë¡¢FEX_CUSTOM ¥Ï¥ó¥É¥é¤Ë¤è¤Ã¤Æ¼ÂÁõ¤·¤¿Á°ÃÖ´¹¤ò»ÈÍѤ·¤ÆÏ¢Ê¬¿ô¤È¤½¤ÎƳ´Ø¿ô¤ò·×»»¤¹¤ë¥×¥í¥°¥é¥àÎã¤ò¼¨¤·¤Þ¤¹¡£

#include <stdio.h>
#include <sunmath.h>
#include <fenv.h>
volatile double p;
void handler(int ex, fex_info_t *info)
{
    info->res.type = fex_double;
    if (ex == FEX_INV_ZMI)
        info->res.val.d = p;
    else
        info->res.val.d = infinity();
}
/*
*  x ¤Î°ÌÃ֤Ƿ¸¿ô a[j] ¤È b[j] ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëϢʬ¿ô¤ò
*  ɾ²Á¤·¡¢´Ø¿ôÃͤò *pf¡¢Æ³´Ø¿ô¤ÎÃͤò *pf1 ¤ÇÊÖ¤·¤Þ¤¹
*/
void continued_fraction(int N, double *a, double *b,
    double x, double *pf, double *pf1)
{
    fex_handler_t    oldhdl; /* ¥Ï¥ó¥É¥é¤ÎÊݸ¤Þ¤¿¤ÏÉü¸µ¤Î¤¿¤á */
    volatile double  t;
    double           f, f1, d, d1, q;
    int              j;
    fex_getexcepthandler(&oldhdl, FEX_DIVBYZERO | FEX_INVALID);
    fex_set_handling(FEX_DIVBYZERO, FEX_NONSTOP, NULL);
    fex_set_handling(FEX_INV_ZDZ | FEX_INV_IDI | FEX_INV_ZMI,
        FEX_CUSTOM, handler);
    f1 = 0.0;
    f = a[N];
    for (j = N - 1; j >= 0; j--) {
        d = x + f;
        d1 = 1.0 + f1;
        q = b[j] / d;
        /* ÊÑ¿ô p ¤ËÂФ¹¤ëÂåÆþ¤È f1 ¤Îɾ²Á¤Î´Ö¤ÇÀµ¤·¤¤½ç½ø¤Å¤±¤ò
°Ý»ý¤¹¤ë¤¿¤á¡¢volatile ÊÑ¿ô t ¤ËÂФ¹¤ë¼¡¤ÎÂåÆþ¤¬É¬ÍפǤ¹ */
        t = f1 = (-d1 / d) * q;
        p = b[j-1] * d1 / b[j];
        f = a[j] + q;
    }
    fex_setexcepthandler(&oldhdl, FEX_DIVBYZERO | FEX_INVALID);
    *pf = f;
    *pf1 = f1;
}
/* ¼¡¤Î·¸¿ô¡¢x = -3¡¢1¡¢4¡¢¤ª¤è¤Ó 5 ¤Ï¤¹¤Ù¤ÆÃæ´ÖÎã³°¤Ë½Ð²ñ¤¤¤Þ¤¹ */
double a[] = { -1.0, 2.0, -3.0, 4.0, -5.0 };
double b[] = { 2.0, 4.0, 6.0, 8.0 };
int main()
{
    double  x, f, f1;
    int     i;
    feraiseexcept(FE_INEXACT); /* ÉÔÀµ³Î¤Ê±é»»¤Î¥í¥°µ­Ï¿¤òËɻߤ·¤Þ¤¹ */
    fex_set_log(stdout);
    fex_set_handling(FEX_COMMON, FEX_ABORT, NULL);
    for (i = -5; i <= 5; i++) {

x = i;
        continued_fraction(4, a, b, x, &f, &f1);
        printf("f(% g) = %12g, f'(% g) = %12g\n", x, f, x, f1);
    }
    return 0;
}


¥×¥í¥°¥é¥à¤Ë¤Ä¤¤¤Æ¤Î¥³¥á¥ó¥È¤¬½ç¤òÄɤäÆÉÕ¤±¤é¤ì¤Æ¤¤¤Þ¤¹¡£Æþ¸ý¤Ç¡¢´Ø¿ôcontinued_fraction ¤Ï¡¢¥¼¥í½ü»»¤ª¤è¤Ó¤¹¤Ù¤Æ¤Î̵¸ú¤Ê±é»»Îã³°¤ËÂФ¹¤ë¸½ºß¤ÎÎã³°½èÍý¥â¡¼¥É¤òÊݸ¤·¤Þ¤¹¡£Â³¤¤¤Æ¡¢¥¼¥í½ü»»¤ËÂФ¹¤ëϢ³¤·¤¿Îã³°½èÍý¤È¡¢3 ¤Ä¤ÎÉÔÄê·Á¤ËÂФ¹¤ëFEX_CUSTOM ¥Ï¥ó¥É¥é¤ò³ÎΩ¤·¤Þ¤¹¡£¤³¤Î¥Ï¥ó¥É¥é¤Ï 0/0 ¤È ̵¸ÂÂç/̵¸ÂÂç¤ÎξÊý¤ò̵¸ÂÂç¤ÇÃÖ´¹¤·¤Þ¤¹¤¬¡¢0*̵¸ÂÂç¤ÏÂç°èÊÑ¿ôp ¤ÎÃͤÇÃÖ´¹¤·¤Þ¤¹¡£Àµ¤·¤¤Ãͤò¶¡µë¤·¤Æ¸å³¤Î 0*̵¸ÂÂç̵¸ú±é»»¤òÃÖ´¹¤¹¤ë¤è¤¦¤Ë¡¢p ¤Ï´Ø¿ô¤òɾ²Á¤¹¤ë¥ë¡¼¥×¤òÄ̤·¤ÆËè²ó·×»»¤·Ä¾¤¹É¬Íפ¬¤¢¤ê¤Þ¤¹¡£¤Þ¤¿¡¢p ¤Ï¥ë¡¼¥×Æâ¤ÇÌÀ¼¨Åª¤Ëµ­½Ò¤µ¤ì¤Æ¤¤¤Ê¤¤¤¿¤á¡¢¥³¥ó¥Ñ¥¤¥é¤¬p ¤òºï½ü¤·¤Ê¤¤¤è¤¦¤Ë¡¢p ¤òvolatile ¤ÈÀë¸À¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£ºÇ¸å¤Ë¡¢¥³¥ó¥Ñ¥¤¥é¤¬p ¤ËÂФ¹¤ëÂåÆþ¤ò¡¢Îã³°¤òȯÀ¸¤µ¤»¤ë²ÄǽÀ­¤Î¤¢¤ë±é»» (¤³¤ì¤ËÂФ·p ¤¬Á°ÃÖ´¹¤ÎÃͤòÄ󶡤¹¤ë) ¤è¤ê¾å¤Þ¤¿¤Ï²¼¤Ë°Üư¤µ¤»¤Ê¤¤¤è¤¦¤Ë¡¢¤½¤Î±é»»¤Î·ë²Ì¤âvolatile ÊÑ¿ô (¥×¥í¥°¥é¥àÆâ¤Ç¤Ït ¤È¸Æ¤Ð¤ì¤ë) ¤ËÂåÆþ¤·¤Þ¤¹¡£fex_setexcepthandler ¤ÎºÇ¸å¤Î¸Æ¤Ó½Ð¤·¤¬¡¢¥¼¥í½ü»»¤È̵¸ú±é»»¤ËÂФ¹¤ëËÜÍè¤Î½èÍý¥â¡¼¥É¤òÉü¸µ¤·¤Þ¤¹¡£

¥á¥¤¥ó¥×¥í¥°¥é¥à¤Ï¡¢fex_set_log ´Ø¿ô¤ò¸Æ¤Ó½Ð¤·¤Æ¡¢Á̵ڿÇÃÇ¤Î¥í¥°µ­Ï¿¤òÍ­¸ú¤Ë¤·¤Þ¤¹¡£¤³¤Î¸Æ¤Ó½Ð¤·¤ò¹Ô¤¦Á°¤Ë¡¢¥á¥¤¥ó¥×¥í¥°¥é¥à¤ÏÉÔÀµ³Î¥Õ¥é¥°¤òȯÀ¸¤µ¤»¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢ÉÔÀµ³Î±é»»¤Îµ­Ï¿¤òËɤ®¤Þ¤¹ (¡ÖÁ̵ڿÇÃǡפÇÀâÌÀ¤·¤Æ¤¤¤ë¤è¤¦¤Ë¡¢FEX_NONSTOP ¥â¡¼¥É¤Ç¤ÏÎã³°¤Î¥Õ¥é¥°¤¬È¯À¸¤¹¤ë¤ÈÎã³°¤¬¥í¥°¤Ëµ­Ï¿¤µ¤ì¤Þ¤»¤ó)¡£¥á¥¤¥ó¥×¥í¥°¥é¥à¤Ï¤Þ¤¿¡¢¶¦ÄÌÎã³°¤ËÂФ·¤Æ FEX_ABORT ¥â¡¼¥É¤ò³ÎΩ¤·¡¢continued_fraction ¤Ë¤è¤Ã¤ÆÌÀ¼¨Åª¤Ë½èÍý¤µ¤ì¤Ê¤¤°Û¾ï¤ÊÎã³°¤¬¥×¥í¥°¥é¥à¤òÄä»ß¤¹¤ë¤³¤È¤òËɤ®¤Þ¤¹¡£¥×¥í¥°¥é¥à¤Ï¡¢ºÇ¸å¤Ë¿ô¤«½ê¤ÇÆÃÄê¤ÎϢʬ¿ô¤òɾ²Á¤·¤Þ¤¹¡£¼¡¤Î½ÐÎÏÎ㤬¼¨¤¹¤è¤¦¤Ë¡¢±é»»¤ÏÃæ´ÖÎã³°¤Ë½Ð²ñ¤¤¤Þ¤¹¡£

f(-5) =     -1.59649,   f'(-5) =      -0.1818
f(-4) =     -1.87302,   f'(-4) =    -0.428193
Floating point division by zero at 0x08048dbe continued_fraction, nonstop mode
  0x08048dc1  continued_fraction
  0x08048eda  main
Floating point invalid operation (inf/inf) at 0x08048dcf continued_fraction, handler: handler
  0x08048dd2  continued_fraction
  0x08048eda  main
Floating point invalid operation (0*inf) at 0x08048dd2 continued_fraction, handler: handler
  0x08048dd8  continued_fraction
  0x08048eda  main
f(-3) =           -3,   f'(-3) =     -3.16667
f(-2) = -4.44089e-16,   f'(-2) =     -3.41667
f(-1) =     -1.22222,   f'(-1) =    -0.444444
f( 0) =     -1.33333,   f'( 0) =     0.203704
f( 1) =           -1,   f'( 1) =     0.333333
f( 2) =    -0.777778,   f'( 2) =      0.12037
f( 3) =    -0.714286,   f'( 3) =    0.0272109
f( 4) =    -0.666667,   f'( 4) =     0.203704
f( 5) =    -0.777778,   f'( 5) =    0.0185185

(x = 1¡¢4¡¢¤ª¤è¤Ó 5 ¤Î¾ì¹ç¤Î·×»»f'(x) ¤ÇȯÀ¸¤¹¤ëÎã³°¤Ï¡¢¥×¥í¥°¥é¥àÆâ¤Çx = -3 ¤Î¤È¤­¤Ëµ¯¤­¤ëÎã³°¤ÈƱ¤¸¥µ¥¤¥È¤ÇȯÀ¸¤¹¤ë¤¿¤á¡¢Á̵ڿÇÃÇ¥á¥Ã¥»¡¼¥¸¤Ë½ÐÎϤµ¤ì¤Þ¤»¤ó¡£)

Á°µ­¤Î¥×¥í¥°¥é¥à¤Ï¡¢Ï¢Ê¬¿ô¤È¤½¤ÎƳ´Ø¿ô¤Îɾ²Á¤Çµ¯¤­¤ëÎã³°¤ò½èÍý¤¹¤ëÊýË¡¤È¤·¤Æ¡¢¤â¤Ã¤È¤â¸úΨ¤¬¤è¤¤ÊýË¡¤ò¼¨¤·¤Æ¤¤¤ë¤È¤Ï¸À¤¨¤Þ¤»¤ó¡£¤½¤Î 1 ¤Ä¤ÎÍýͳ¤Ï¡¢É¬ÍפÎ̵ͭ¤Ë¤«¤«¤ï¤é¤º¡¢¥ë¡¼¥×¤¬·«¤êÊÖ¤µ¤ì¤ë¤´¤È¤ËÁ°ÃÖ´¹¤ÎÃͤò·×»»¤·Ä¾¤¹É¬Íפ¬¤¢¤ë¤³¤È¤Ç¤¹¡£¤³¤Î¾ì¹ç¡¢Á°ÃÖ´¹¤ÎÃͤη׻»¤Ë¤ÏÉâÆ°¾®¿ôÅÀ½ü»»¤¬´Þ¤Þ¤ì¤Þ¤¹¤¬¡¢ºÇ¿·¤Î SPARC ¤ª¤è¤Ó x86 ¥×¥í¥»¥Ã¥µ¤Ç¤ÏÉâÆ°¾®¿ôÅÀ½ü»»¤ÏÈæ³ÓŪÃÙ¤¤±é»»¤Ç¤¹¡£¤Þ¤¿¡¢¥ë¡¼¥×¼«ÂΤˤ¹¤Ç¤Ë 2 ¤Ä¤Î½ü»»¤¬´Þ¤Þ¤ì¤Æ¤ª¤ê¡¢¤Û¤È¤ó¤É¤Î SPARC ¤ª¤è¤Ó x86 ¥×¥í¥»¥Ã¥µ¤Ï 2 ¤Ä¤Î½ü»»±é»»¤ÎÎã³°¤ò¥ª¡¼¥Ð¡¼¥é¥Ã¥×¤Ç¤­¤Ê¤¤¤¿¤á¡¢½ü»»¤¬¥ë¡¼¥×Æâ¤Î¥Ü¥È¥ë¥Í¥Ã¥¯¤È¤Ê¤ê¤ä¤¹¤¤¤Î¤Ç¤¹¡£Ê̤νü»»¤òÄɲ乤ë¤È¥Ü¥È¥ë¥Í¥Ã¥¯¤Ï¤µ¤é¤Ë°­²½¤·¤Þ¤¹¡£

1 ¤Ä¤Î½ü»»¤À¤±¤Ç¤¹¤à¤è¤¦¤Ë¥ë¡¼¥×¤ò½ñ¤­Ä¾¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¼ÂºÝ¡¢Á°ÃÖ´¹Ãͤη׻»¤Ï½ü»»¤òɬÍפȤ·¤Þ¤»¤ó (¤³¤Î¤è¤¦¤Ë¥ë¡¼¥×¤ò½ñ¤­Ä¾¤¹¤Ë¤Ï¡¢b ÇÛÎóÆâ¤Î·¸¿ô¤ÎÎÙÀÜÍ×ÁÇÈæ¤òÁ°¤â¤Ã¤Æ·×»»¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹)¡£¤³¤ì¤Ë¤è¤ê¡¢Ê£¿ô¤Î½ü»»¤ò´Þ¤à±é»»¤Î¥Ü¥È¥ë¥Í¥Ã¥¯¤ÏÇÓ½ü¤µ¤ì¤Þ¤¹¤¬¡¢Á°ÃÖ´¹Ãͤη׻»¤Ë´Þ¤Þ¤ì¤ë¤¹¤Ù¤Æ¤Î»»½Ñ±é»»¤¬½ü¤«¤ì¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤Þ¤¿¡¢Á°ÃÖ´¹Ãͤȱ黻·ë²Ì¤ÎξÊý¤¬volatile ÊÑ¿ô¤ËÁ°ÃÖ´¹¤µ¤ì¤ë¤è¤¦¤Ë³ä¤êÅö¤Æ¤ëɬÍפ¬¤¢¤ë¤¿¤á¡¢¥×¥í¥°¥é¥à¤Î®ÅÙ¤òÄã²¼¤µ¤»¤ë¥á¥â¥ê¡¼±é»»¤¬Áý¤¨¤Þ¤¹¡£¤³¤ì¤é¤ÎÂåÆþ¤Ï¡¢¥³¥ó¥Ñ¥¤¥é¤¬¤¢¤ë¼ï¤Î¥­¡¼Áàºî¤òºÆÍ׵᤹¤ë¤³¤È¤òËɻߤ¹¤ë¤¿¤á¤Ë·ç¤«¤»¤Þ¤»¤ó¤¬¡¢¥³¥ó¥Ñ¥¤¥é¤¬¤Û¤«¤Î̵´Ø·¸¤Ê±é»»¤òºÆÍ׵᤹¤ë¤³¤È¤âËɻߤ·¤Æ¤·¤Þ¤¤¤Þ¤¹¡£¤³¤ÎÎã¤Î¤è¤¦¤ËÁ°ÃÖ´¹¤ò²ð¤·¤ÆÎã³°¤ò½èÍý¤¹¤ë¤È¡¢¥á¥â¥ê¡¼±é»»¤¬Áý¤¨¡¢Ä̾ï¤Ç¤Ï²Äǽ¤ÊºÇŬ²½¤¬¹Ô¤ï¤ì¤Ê¤¯¤Ê¤ê¤Þ¤¹¡£¤³¤ì¤é¤ÎÎã³°¤ò¡¢¹¹¤Ë¸úΨ¤è¤¯½èÍý¤¹¤ë¤³¤È¤Ï²Äǽ¤Ç¤·¤ç¤¦¤«¡£

¹â®¤ÊÁ°ÃÖ´¹¤ËÂФ¹¤ëÆÃÊ̤ʥϡ¼¥É¥¦¥§¥¢¥µ¥Ý¡¼¥È¤¬¤Ê¤¤¾ì¹ç¡¢¤³¤ÎÎã¤Ë¤ª¤±¤ëÎã³°¤ò¤â¤Ã¤È¤â¸úΨ¤è¤¯½èÍý¤¹¤ë¤Ë¤Ï¡¢¼¡¤ÎÎã¤Ë¼¨¤¹¤è¤¦¤Ë¥Õ¥é¥°¤ò»ÈÍѤ¹¤ë¤³¤È¤Ç¤·¤ç¤¦¡£

#include <stdio.h>
#include <math.h>
#include <fenv.h>
/*
* x ¤Î°ÌÃ֤Ƿ¸¿ô a[j] ¤È b[j] ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëϢʬ¿ô¤ò
* ɾ²Á¤·¡¢´Ø¿ôÃͤò *pf¡¢Æ³´Ø¿ô¤ÎÃͤò *pf1 ¤ÇÊÖ¤·¤Þ¤¹
*/
void continued_fraction(int N, double *a, double *b,
    double x, double *pf, double *pf1)
{
    fex_handler_t  oldhdl;
    fexcept_t      oldinvflag;
    double         f, f1, d, d1, pd1, q;
    int            j;
    fex_getexcepthandler(&oldhdl, FEX_DIVBYZERO | FEX_INVALID);
    fegetexceptflag(&oldinvflag, FE_INVALID);
    fex_set_handling(FEX_DIVBYZERO | FEX_INV_ZDZ | FEX_INV_IDI |
        FEX_INV_ZMI, FEX_NONSTOP, NULL);
    feclearexcept(FE_INVALID);
    f1 = 0.0;
    f = a[N];
    for (j = N - 1; j >= 0; j--) {
        d = x + f;
        d1 = 1.0 + f1;
        q = b[j] / d;
        f1 = (-d1 / d) * q;
        f = a[j] + q;
    }
    if (fetestexcept(FE_INVALID)) {
        /* recompute and test for NaN */
        f1 = pd1 = 0.0;
        f = a[N];
        for (j = N - 1; j >= 0; j--) {
            d = x + f;
            d1 = 1.0 + f1;
            q = b[j] / d;
            f1 = (-d1 / d) * q;
            if (isnan(f1))
                f1 = b[j] * pd1 / b[j+1];
            pd1 = d1;
            f = a[j] + q;
        }
    }
    fesetexceptflag(&oldinvflag, FE_INVALID);
    fex_setexcepthandler(&oldhdl, FEX_DIVBYZERO | FEX_INVALID);
    *pf = f;
    *pf1 = f1;
}


¤³¤ÎÎã¤Ç¤Ï¡¢ºÇ½é¤Î¥ë¡¼¥×¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎϢ³¥â¡¼¥É¤Çf(x) ¤Èf'(x) ¤Î·×»»¤ò»î¤ß¤Æ¤¤¤Þ¤¹¡£Ìµ¸ú¥Õ¥é¥°¤¬È¯À¸¤¹¤ë¤È¡¢2 ÈÖÌܤΥ롼¥×¤Ï NaN ¤Î³°·Á¤ò¥Æ¥¹¥È¤·¤Æf(x) ¤Èf'(x) ¤òÌÀ¼¨Åª¤ËºÆ·×»»¤·¤Þ¤¹¡£Ä̾̵¸ú±é»»Îã³°¤ÏȯÀ¸¤·¤Ê¤¤¤¿¤á¡¢¥×¥í¥°¥é¥à¤ÏºÇ½é¤Î¥ë¡¼¥×¤À¤±¤ò¼Â¹Ô¤·¤Þ¤¹¡£¤³¤Î¥ë¡¼¥×¤Ë¤Ïvolatile ÊÑ¿ô¤ËÂФ¹¤ë»²¾È¤â;ʬ¤Ê»»½Ñ±é»»¤â´Þ¤Þ¤ì¤Ê¤¤¤¿¤á¡¢¥ë¡¼¥×¤Ï¥³¥ó¥Ñ¥¤¥é¤¬²Äǽ¤È¤¹¤ë¤«¤®¤ê¤Î®Å٤Ǽ¹Ԥµ¤ì¤Þ¤¹¡£¤³¤Î¸úΨ¤òÆÀ¤ë¤¿¤á¤Ë¤Ï¡¢Îã³°¤¬È¯À¸¤¹¤ë¥±¡¼¥¹¤ò½èÍý¤¹¤ë¤¿¤á¤Ë¡¢2 ÈÖÌܤΥ롼¥×¤òºÇ½é¤Î¥ë¡¼¥×¤È¤Û¤È¤ó¤ÉƱ¤¸¤è¤¦¤Ëµ­½Ò¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤³¤Î¥È¥ì¡¼¥É¥ª¥Õ¤Ï¡¢ÉâÆ°¾®¿ôÅÀÎã³°½èÍý¤¬Ä¾Ì̤¹¤ëŵ·¿Åª¤Ê¥¸¥ì¥ó¥Þ¤Ç¤¹¡£

libm9x.so ¤Ï¼ç¤Ë C ¤ª¤è¤Ó C++ ¥×¥í¥°¥é¥à¤Ç¤Î»ÈÍѤòÁÛÄꤷ¤¿¤â¤Î¤Ç¤¹¤¬¡¢
Sun ¤Î FORTRAN ¸À¸ì¤Ë¤ª¤±¤ëÁê¸ß±¿ÍÑÀ­¤Îµ¡Ç½¤ò³èÍѤ¹¤ì¤Ð¡¢FORTRAN ¥×¥í¥°¥é¥à¤«¤é¤â°ìÉô¤Îlibm9x.so ´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£


Ãí -°ì´Ó¤·¤¿Æ°ºî¤òÊݤĤ¿¤á¡¢libm9x.so ¤ÎÎã³°½èÍý´Ø¿ô¤È¡¢ieee_flags ¤ª¤è¤Óieee_handler ´Ø¿ô¤ÎξÊý¤òƱ¤¸¥×¥í¥°¥é¥àÆâ¤Ç»ÈÍѤ¹¤ë¤³¤È¤ÏÈò¤±¤Æ¤¯¤À¤µ¤¤¡£

¼¡¤Ë¡¢Á°ÃÖ´¹¤ò»ÈÍѤ·¤ÆÏ¢Ê¬¿ô¤È¤½¤ÎƳ´Ø¿ô¤òɾ²Á¤¹¤ë¡¢FORTRAN ¤Ë¤è¤ë¥×¥í¥°¥é¥àÎã¤ò¼¨¤·¤Þ¤¹ (SPARC ¤Î¤ß)¡£

c
c Á°ÃÖ´¹¥Ï¥ó¥É¥é
c
      subroutine handler(ex, info)
      structure /fex_numeric_t/
          integer type
          union
          map
              integer i
          end map
          map
              integer*8 l
          end map
          map
              real f
          end map
          map
              real*8 d
          end map
          map
              real*16 q
          end map
          end union
      end structure
      structure /fex_info_t/
          integer op, flags
          record /fex_numeric_t/ op1, op2, res
      end structure
      integer ex
      record /fex_info_t/ info
      common /presub/ p
      double precision p, d_infinity
      volatile p
c 4 = fex_double; Äê¿ô¤Ë¤Ä¤¤¤Æ¤Ï <fenv.h> ¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
      info.res.type = 4
c x'80' = FEX_INV_ZMI
      if (loc(ex) .eq. x'80') then
          info.res.d = p
      else
          info.res.d = d_infinity()
      endif
      return
      end
c
c x ¤Î°ÌÃ֤Ƿ¸¿ô a[j] ¤È b[j] ¤Ë¤è¤Ã¤Æ»ØÄꤵ¤ì¤ëϢʬ¿ô¤ò
c ɾ²Á¤·¡¢´Ø¿ôÃͤò f¡¢Æ³´Ø¿ô¤ÎÃͤò f1 ¤ÇÊÖ¤·¤Þ¤¹
c
      subroutine continued_fraction(n, a, b, x, f, f1)
      integer n
      double precision a(*), b(*), x, f, f1
      common /presub/ p
      integer j, oldhdl
      dimension oldhdl(24)
      double precision d, d1, q, p, t
      volatile p, t
      external fex_getexcepthandler, fex_setexcepthandler
      external fex_set_handling, handler
c$pragma c(fex_getexcepthandler, fex_setexcepthandler)
c$pragma c(fex_set_handling)
c x'ff2' = FEX_DIVBYZERO | FEX_INVALID
      call fex_getexcepthandler(oldhdl, %val(x'ff2'))
c x'2' = FEX_DIVBYZERO, 0 = FEX_NONSTOP
      call fex_set_handling(%val(x'2'), %val(0), %val(0))
c x'b0' = FEX_INV_ZDZ | FEX_INV_IDI | FEX_INV_ZMI, 3 = FEX_CUSTOM
      call fex_set_handling(%val(x'b0'), %val(3), handler)
      f1 = 0.0d0
      f = a(n+1)
      do j = n, 1, -1
          d = x + f
          d1 = 1.0d0 + f1
          q = b(j) / d
          f1 = (-d1 / d) * q
c
c         ÊÑ¿ô p ¤ËÂФ¹¤ëÂåÆþ¤È f1 ¤Îɾ²Á¤Î´Ö¤ÇÀµ¤·¤¤½ç½ø¤Å¤±
c         ¤ò°Ý»ý¤¹¤ë¤¿¤á¡¢volatile ÊÑ¿ô t ¤ËÂФ¹¤ë¼¡¤ÎÂåÆþ¤¬
c         ɬÍפǤ¹
          t = f1
          p = b(j-1) * d1 / b(j)
          f = a(j) + q
      end do
      call fex_setexcepthandler(oldhdl, %val(x'ff2'))
      return
      end
c
c ¥á¥¤¥ó¥×¥í¥°¥é¥à
c
      program cf
      integer i
      double precision a, b, x, f, f1
      dimension a(5), b(4)
      data a /-1.0d0, 2.0d0, -3.0d0, 4.0d0, -5.0d0/
      data b /2.0d0, 4.0d0, 6.0d0, 8.0d0/
      external fex_set_handling
c$pragma c(fex_set_handling)
c x'ffa' = FEX_COMMON, 1 = FEX_ABORT
      call fex_set_handling(%val(x'ffa'), %val(1), %val(0))
      do i = -5, 5
          x = dble(i)
          call continued_fraction(4, a, b, x, f, f1)
          write (*, 1) i, f, i, f1
      end do
    1 format('f(', I2, ') = ', G12.6, ', f''(', I2, ') = ', G12.6)
      end


¤³¤Î¥×¥í¥°¥é¥à¤Î½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

f(-5) = -1.59649    , f'(-5) = -.181800
f(-4) = -1.87302    , f'(-4) = -.428193
f(-3) = -3.00000    , f'(-3) = -3.16667
f(-2) = -.444089E-15, f'(-2) = -3.41667
f(-1) = -1.22222    , f'(-1) = -.444444
f( 0) = -1.33333    , f'( 0) = 0.203704
f( 1) = -1.00000    , f'( 1) = 0.333333
f( 2) = -.777778    , f'( 2) = 0.120370
f( 3) = -.714286    , f'( 3) = 0.272109E-01
f( 4) = -.666667    , f'( 4) = 0.203704
f( 5) = -.777778    , f'( 5) = 0.185185E-01
 Note: IEEE floating-point exception flags raised:
    Inexact;  Division by Zero;  Invalid Operation;
 IEEE floating-point exception traps enabled:
    overflow;  division by zero;  invalid operation;
 See the Numerical Computation Guide, ieee_flags(3M), ieee_handler(3M)
[ÆüËܸìÌõ]
Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤¬È¯À¸¤·¤Þ¤·¤¿:
ÉÔÀµ³Î¡¢¥¼¥í¤Ë¤è¤ë½ü»»¡¢Ìµ¸ú¤Ê±é»»
°Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤Î¥È¥é¥Ã¥×¤¬Í­¸ú¤Ç¤¹:
¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¡¢¥¼¥í¤Ë¤è¤ë½ü»»¡¢Ìµ¸ú¤Ê±é»»
¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_flagsieee_handler

Á°Àá¤Ç¤Ï¡¢ieee_handler ¤ò»ÈÍѤ·¤¿Îã¤ò¼¨¤·¤Þ¤·¤¿¡£°ìÈÌŪ¤Ë¡¢ieee_handler ¤Èsigfpe ¤Î¤É¤Á¤é¤«¤Î»ÈÍѤòÁªÂò¤¹¤ë¾ì¹ç¤Ï¡¢Á°¼Ô¤ò¤ª´«¤á¤·¤Þ¤¹¡£


Ãí -sigfpe ¤Ï¡¢Solaris ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°´Ä¶­¤Î¤ß¤Ç»ÈÍѲÄǽ¤Ç¤¹¡£

SPARC¤Ç¤Ï¡¢¤¿¤È¤¨¤Ð¡¢À°¿ô±é»»Îã³°¤ò¥È¥é¥Ã¥×¤¹¤ëºÝ¤Ë»ÈÍѤ¹¤ë¥Ï¥ó¥É¥é¤¬sigfpe ¤À¤È¤·¤Þ¤¹¡£¼¡¤ÎÎã¤ÏÀ°¿ô¤Î¥¼¥í½ü»»¤Ç¥È¥é¥Ã¥×¤·¡¢·ë²Ì¤ò¥æ¡¼¥¶¡¼¤Î»ØÄꤷ¤¿ÃͤËÃÖ¤­´¹¤¨¤Æ¤¤¤Þ¤¹¡£

/* À°¿ô¤Î¥¼¥í½ü»»Îã³°¤òÀ¸À®¤¹¤ë */
#include <siginfo.h>
#include <ucontext.h>
#include <signal.h>
void int_handler(int sig, siginfo_t *sip, ucontext_t *uap);
int main() {
    int a, b, c;
/*
 * sigfpe(3) ¤ò»ÈÍѤ·¤Æ¡¢À°¿ô¥¼¥í½ü»»¤Ç»ÈÍѤ¹¤ë¥·¥°¥Ê¥ë¥Ï¥ó¥É¥é¤È¤·¤Æ
 * int_handler ¤òÀßÄꤹ¤ë
 */
/*
 * À°¿ô¤Î¥¼¥í½ü»»¤ËÂФ¹¤ë¥·¥°¥Ê¥ë¥Ï¥ó¥É¥é¤¬ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤¤¤È¡¢
 * À°¿ô¤Î¥¼¥í½ü»»¤Ï°Û¾ï½ªÎ»¤¹¤ë
 */
        sigfpe(FPE_INTDIV, int_handler);
        a = 4;
        b = 0;
        c = a / b;
        printf("%d / %d = %d\n\n", a, b, c);
        return(0);
}
void int_handler(int sig, siginfo_t *sip, ucontext_t *uap) {
     printf("Signal %d, code %d, at addr %x\n",
     sig, sip->si_code, sip->_data._fault._addr);
/*
 * ¥×¥í¥°¥é¥à¥«¥¦¥ó¥¿¤òÁý¤ä¤¹¡£¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ï¡¢
 * ¤³¤ì¤òÉâÆ°¾®¿ôÅÀÎã³°¤ËÂФ·¤Æ¼«Æ°Åª¤Ë¹Ô¤¦¡£
 * À°¿ô¤Î¥¼¥í½ü»»¤ËÂФ·¤Æ¤Ï¹Ô¤ï¤Ê¤¤¡£
 */
        uap->uc_mcontext.gregs[REG_PC] =
        uap->uc_mcontext.gregs[REG_nPC];
}

FORTRAN ¤Î¥µ¥Ö¥ë¡¼¥Á¥ó¤ò¸Æ¤Ó½Ð¤¹ C ¥É¥é¥¤¥Ð¤ÎÎã¤ò¼¨¤·¤Þ¤¹¡£C ¤È FORTRAN ¤Ç¤Îưºî¤Ë´Ø¤¹¤ë¾ÜºÙ¤Ï¡¢Å¬Åö¤Ê C ¤ª¤è¤Ó FORTRAN ¤Î¥Þ¥Ë¥å¥¢¥ë¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£°Ê²¼¤Ï C ¥É¥é¥¤¥Ð¤Ç¤¹ (¥Õ¥¡¥¤¥ëdriver.c ¤ËÊݸ¤·¤Þ¤¹)¡£

/*
 * °Ê²¼¤ÎÊýË¡¤ò¼¨¤¹¥Ç¥â¥×¥í¥°¥é¥à¤Ç¤¹¡£
 *
 * 1. ÇÛÎó°ú¿ô¤òÅϤ·¤Æ¡¢f77 ¥µ¥Ö¥ë¡¼¥Á¥ó¤ò C ¤«¤é¸Æ¤Ó½Ð¤¹ÊýË¡
 * 2. ñÀºÅÙ f77 ´Ø¿ô¤ò C ¤«¤é¸Æ¤Ó½Ð¤¹ÊýË¡
 * 3. ÇÜÀºÅÙ f77 ´Ø¿ô¤ò C ¤«¤é¸Æ¤Ó½Ð¤¹ÊýË¡
 */
extern int      demo_one_(double *);
extern float    demo_two_(float *);
extern double   demo_three_(double *);
int main()
{
double          array[3][4];
float           f, g;
double          x, y;
int             i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
array[i][j] = i + 2*j;
g = 1.5;
y = g;
/* ÇÛÎó¤ò fortran ´Ø¿ô¤ËÅϤ¹ (ÇÛÎó¤Î½ÐÎÏ) */
demo_one_(&array[0][0]);
printf(" from the driver\n");
for (i = 0; i < 3; i++) {
for (j = 0; j < 4; j++)
printf("    array[%d][%d] = %e\n",
                    i, j, array[i][j]);
printf("\n");
}
/* ñÀºÅÙ fortran ´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹ */
f = demo_two_(&g);
printf(
         " f = sin(g) from a single precision fortran function\n");
printf("    f, g: %8.7e, %8.7e\n", f, g);
printf("\n");
/* ÇÜÀºÅÙ fortran ´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹ */
x = demo_three_(&y);
printf(
         " x = sin(y) from a double precision fortran function\n");
printf("    x, y: %18.17e, %18.17e\n", x, y);
ieee_retrospective_();
return(0);
}

¥Õ¥¡¥¤¥ëdrivee.f ¤Ë FORTRAN ¤Î¥µ¥Ö¥ë¡¼¥Á¥ó¤òÊݸ¤·¤Þ¤¹¡£

      subroutine demo_one(array)
      double precision array(4,3)
      print *, 'from the fortran routine:'
      do 10 i =1,4
         do 20 j = 1,3
            print *, '   array[', i, '][', j, '] = ', array(i,j)
 20      continue
      print *
 10   continue
      return
      end
      real function demo_two(number)
      real number
      demo_two = sin(number)
      return
      end
      double precision function demo_three(number)
      double precision number
      demo_three = sin(number)
      return
      end

¤½¤ì¤«¤é¡¢¥³¥ó¥Ñ¥¤¥ë¤È¥ê¥ó¥¯¤ò¹Ô¤¤¤Þ¤¹¡£

cc -c driver.c
f77 -c drivee.f
demo_one:
demo_two:
demo_three:
f77 -o driver driver.o drivee.o

½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£

 from the fortran routine:
    array[  1][  1] =   0.
    array[  1][  2] =     1.0000000000000
    array[  1][  3] =     2.0000000000000
    array[  2][  1] =     2.0000000000000
    array[  2][  2] =     3.0000000000000
    array[  2][  3] =     4.0000000000000
    array[  3][  1] =     4.0000000000000
    array[  3][  2] =     5.0000000000000
    array[  3][  3] =     6.0000000000000
    array[  4][  1] =     6.0000000000000
    array[  4][  2] =     7.0000000000000
    array[  4][  3] =     8.0000000000000
 from the driver
    array[0][0] = 0.000000e+00
    array[0][1] = 2.000000e+00
    array[0][2] = 4.000000e+00
    array[0][3] = 6.000000e+00
    array[1][0] = 1.000000e+00
    array[1][1] = 3.000000e+00
    array[1][2] = 5.000000e+00
    array[1][3] = 7.000000e+00
    array[2][0] = 2.000000e+00
    array[2][1] = 4.000000e+00
    array[2][2] = 6.000000e+00
    array[2][3] = 8.000000e+00
 f = sin(g) from a single precision fortran function
    f, g: 9.9749500e-01, 1.5000000e+00
 x = sin(y) from a double precision fortran function
    x, y: 9.97494986604054446e-01, 1.50000000000000000e+00

ɽ A-1 ¤Ï¡¢SPARC ¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Î¥Ç¥Ð¥Ã¥°¥³¥Þ¥ó¥É¤ÎÎã¤Ç¤¹¡£

¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤ÎÀßÄê

´Ø¿ôstop in myfunctmyfunct:b
¹ÔÈÖ¹æstop at 29
ÀäÂÐ¥¢¥É¥ì¥¹
23a8:b
ÁêÂÐ¥¢¥É¥ì¥¹
main+0x40:b
¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤ËÍè¤ë¤Þ¤Ç¼Â¹Ôrun:r
¥½¡¼¥¹¥³¡¼¥É¤Îɽ¼¨list<pc,10?ia
ÉâÆ°¾®¿ôÅÀ¥ì¥¸¥¹¥¿¤Îɽ¼¨

IEEE ñÀºÅÙprint $f0<f0=X
Åù²Á¤Î 10 ¿Ê¿ôprint -fx $f0<f0=f
IEEE ÇÜÀºÅÙprint $f0f1<f0=X; <f1=X
Åù²Á¤Î 10 ¿Ê¿ôprint -flx $f0f1
print -flx $d0
<f0=F
Á´ÉâÆ°¾®¿ôÅÀ¥ì¥¸¥¹¥¿¤Îɽ¼¨regs -F$x for f0-f15
$X for f16-f31
Á´¥ì¥¸¥¹¥¿¤Îɽ¼¨regs$r; $x; $X
ÉâÆ°¾®¿ôÅÀ¾õÂ֥쥸¥¹¥¿¤Îɽ¼¨print -fx $fsr<fsr=X
f0 ¤ËñÀºÅÙ 1.0 ¤òÀßÄêassign $f0=1.03f800000>f0
f0/f1 ¤ËÇÜÀºÅÙ 1.0 ¤òÀßÄêassign $f0f1=1.03ff00000>f0; 0>f1
¼Â¹Ô¤ò·Ñ³cont:c
¥·¥ó¥°¥ë¥¹¥Æ¥Ã¥×step (or next):s
¥Ç¥Ð¥Ã¥¬¤ò½ªÎ»quit$q


ɽ A-2 ¤Ï¡¢x86 ¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Î¥Ç¥Ð¥Ã¥°¥³¥Þ¥ó¥É¤ÎÎã¤Ç¤¹

¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤ÎÀßÄê

´Ø¿ôstop in myfunctmyfunct:b
¹ÔÈÖ¹æstop at 29
ÀäÂÐ¥¢¥É¥ì¥¹
23a8:b
ÁêÂÐ¥¢¥É¥ì¥¹
main+0x40:b
¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤ËÍè¤ë¤Þ¤Ç¼Â¹Ôrun:r
¥½¡¼¥¹¥³¡¼¥É¤Îɽ¼¨list<pc,10?ia
ÉâÆ°¾®¿ôÅÀ¥ì¥¸¥¹¥¿¤Îɽ¼¨
print $st0
...
print $st7
$x
Á´¥ì¥¸¥¹¥¿¤Îɽ¼¨examine &$gs/19X$r
ÉâÆ°¾®¿ôÅÀ¾õÂ֥쥸¥¹¥¿¤Îɽ¼¨examine &$fstat/X<fstat=X
¤Þ¤¿¤Ï $x
¼Â¹Ô¤ò·Ñ³cont:c
¥·¥ó¥°¥ë¥¹¥Æ¥Ã¥×step (or next):s
¥Ç¥Ð¥Ã¥¬¤ò½ªÎ»quit$q


¤Î¥ë¡¼¥Á¥ómyfunction ¤ËÂбþ¤¹¤ë¥³¡¼¥É¤ÎÀèÆ¬¤Ë¡¢¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤òÀßÄꤹ¤ë 2 ¤Ä¤ÎÊýË¡¤ò¼¨¤·¤Þ¤¹¡£ºÇ½é¤ÎÊýË¡¤Ç¤Ï¡¢¼¡¤Î¤è¤¦¤Ëµ­½Ò¤¹¤ë¤À¤±¤Ç¤¹¤ß¤Þ¤¹¡£

myfunction:b

2 ÈÖÌܤÎÊýË¡¤Ç¤Ï¡¢ ¤ËÂбþ¤·¤Æ¤¤¤ë¥³¡¼¥ÉÉô¤ÎÀèÆ¬¤ËÁêÅö¤¹¤ëÀäÂÐ¥¢¥É¥ì¥¹¤òÄ´¤Ù¤¿¸å¡¢¤½¤ÎÀäÂÐ¥¢¥É¥ì¥¹¤Ë¥Ö¥ì¡¼¥¯¤òÀßÄꤷ¤Þ¤¹¡£

myfunction=X
        23a8
23a8:b

f95 ¤Ç¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤ë FORTRAN ¥×¥í¥°¥é¥àÆâ¤Î¥á¥¤¥ó¥µ¥Ö¥ë¡¼¥Á¥ó¤Ï¡¢adb ¤Ø¤ÎMAIN_ ¤È¤·¤ÆÃΤé¤ì¤Æ¤¤¤Þ¤¹¡£adb ¤ÎMAIN_ ¤Ç¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤òÀßÄꤹ¤ë¤Ë¤Ï¡¢¼¡¤Î¤è¤¦¤Ë»ØÄꤷ¤Þ¤¹¡£

MAIN_:b

ÉâÆ°¾®¿ôÅÀ¥ì¥¸¥¹¥¿¤ÎÆâÍÆ¤òÄ´¤Ù¤ë¾ì¹ç¡¢dbx ¥³¥Þ¥ó¥É¤Î&$f0/X ¤Ë¤è¤Ã¤ÆÉ½¼¨¤µ¤ì¤ë 16 ¿Ê¿ôÃÍ¤Ï IEEE ɽ¸½¤Ç¤¢¤ê¡¢¤½¤Î¿ô»ú¤Î 10 ¿Êɽ¸½¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£SPARC¤Ç¤Ï adb ¥³¥Þ¥ó¥É¤Î ¤È ¤Ï¡¢16 ¿Ê¿ôɽ¸½¤È 10 ¿Ê¿ôÃͤÎξÊý¤òɽ¼¨¤·¤Þ¤¹¡£x86 ¤Ç¤Ï¡¢adb ¥³¥Þ¥ó¥É¤Î$x ¤Ï 10 ¿Ê¿ô¤Î¤ß¤òɽ¼¨¤·¤Þ¤¹¡£SPARC ¤Ç¤ÏÇÜÀºÅÙ¤ÎÃͤˤĤ¤¤Æ¤Ï¡¢´ñ¿ôÈÖ¹æ¤Î¥ì¥¸¥¹¥¿¤Î²£¤Ë 10 ¿Ê¿ôÃͤ¬É½¼¨¤µ¤ì¤Þ¤¹¡£

SPARC ¤Ç¤Ï¡¢ÉâÆ°¾®¿ôÅÀ¿ô¤òɽ¼¨¤¹¤ë¾ì¹ç¡¢¥ì¥¸¥¹¥¿¤Î¥µ¥¤¥º¤Ï 32 ¥Ó¥Ã¥È¤Ç¤¢¤ê¡¢1 ¤Ä¤ÎñÀºÅÙÉâÆ°¾®¿ôÅÀ¿ô¤Ï 32 ¥Ó¥Ã¥È¤òÀê¤á (¤·¤¿¤¬¤Ã¤Æ 1 ¤Ä¤Î¥ì¥¸¥¹¥¿¤Ë¼ý¤Þ¤ë)¡¢ÇÜÀºÅÙÉâÆ°¾®¿ôÅÀ¿ô¤Ï 64 ¥Ó¥Ã¥È¤òÀê¤á¤ë (¤·¤¿¤¬¤Ã¤ÆÇÜÀºÅÙ¿ô 1 ¤Ä¤òÊÝ»ý¤¹¤ë¤Ë¤Ï 2 ¤Ä¤Î¥ì¥¸¥¹¥¿¤¬»ÈÍѤµ¤ì¤ë) ¤³¤È¤ò³Ð¤¨¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡£16 ¿Ê¿ôɽ¸½¤Ç¤Ï¡¢32 ¥Ó¥Ã¥È¤Ï 8 ·å¤Î¿ô»ú¤ËÁêÅö¤·¤Þ¤¹¡£adb ¤Çɽ¼¨¤·¤¿ÉâÆ°¾®¿ôÅÀ¥æ¥Ë¥Ã¥È¤Ç¤Ï¡¢É½¼¨¤Ï¼¡¤Î¤è¤¦¤Ê·Á¤Ç¹Ô¤ï¤ì¤Þ¤¹¡£

< ÉâÆ°¾®¿ôÅÀ¥ì¥¸¥¹¥¿Ì¾> <IEEE 16 ¿Ê¿ô¤ÎÃÍ> <ñÀºÅÙ> <ÇÜÀºÅÙ>

SPARC ¤Ç¤Ï¡¢3 ÈÖÌܤÎÍó¤Ë¤Ï¡¢2 ÈÖÌܤÎÍó¤Ë¼¨¤µ¤ì¤¿ IEEE 16 ¿Ê¿ô¤òñÀºÅ٤Π10 ¿Ê¿ô¤ËÊÑ´¹¤·¤¿Ãͤ¬ÊÝ»ý¤µ¤ì¤Æ¤¤¤Þ¤¹¡£4 ÈÖÌܤÎÍó¤Ç¤Ï¡¢¥ì¥¸¥¹¥¿¤ÎÂФò²ò¼á¤·¤Æ¤¤¤Þ¤¹¡£

SPARC ¤Ç¤Ï¡¢f10 ¤Èf11 ¤ò 64 ¥Ó¥Ã¥È¤Î IEEE ÇÜÀºÅÙ¿ô¤È¤·¤Æ²ò¼á¤·¤Æ¤¤¤Þ¤¹¡£1 ¤Ä¤ÎÇÜÀºÅÙÃͤòÊÝ»ý¤¹¤ë¤Î¤Ëf10 ¤Èf11 ¤ò»È¤¦¤Î¤Ç¡¢¤½¤ÎÃͤκǽé¤Î 32 ¥Ó¥Ã¥È¤Î (f10 ¹Ô¤Ç¤Î)7ff00000 ¤Ï+NaN ¤È¤Ï²ò¼á¤µ¤ì¤Þ¤»¤ó¡£64 ¥Ó¥Ã¥È7ff00000 00000000 Á´ÂΤβò¼á¤Ç¤¢¤ë+̵¸ÂÂç¤Ï¡¢°ÕÌ£¤Î¤¢¤ë²ò¼á¤Ë¤Ê¤ê¤Þ¤¹¡£

SPARC ¤Ç¤Ï¡¢ºÇ½é¤Î 16 ¤ÎÉâÆ°¾®¿ôÅÀ¥Ç¡¼¥¿¥ì¥¸¥¹¥¿¤òɽ¼¨¤¹¤ë¤¿¤á¤Ë»ÈÍѤµ¤ì¤Æ¤¤¤ëadb ¥³¥Þ¥ó¥É$x ¤Ï¡¢fsr (ÉâÆ°¾®¿ôÅÀ¥¹¥Æ¡¼¥¿¥¹¥ì¥¸¥¹¥¿) ¤âɽ¼¨¤·¤Æ¤¤¤Þ¤¹¡£

$x
fsr   40020
f0400921fb     +2.1426990e+00
f154442d18     +3.3702806e+12     +3.1415926535897931e+00
f2       2     +2.8025969e-45
f3       0     +0.0000000e+00     +4.2439915819305446e-314
f440000000     +2.0000000e+00
f5       0     +0.0000000e+00     +2.0000000000000000e+00
f63de0b460     +1.0971904e-01
f7       0     +0.0000000e+00     +1.2154188766544394e-10
f83de0b460     +1.0971904e-01
f9       0     +0.0000000e+00     +1.2154188766544394e-10
f107ff00000     +NaN
f11       0     +0.0000000e+00     +Infinity
f12ffffffff     -NaN
f13ffffffff     -NaN                -NaN
f14ffffffff     -NaN
f15ffffffff     -NaN                -NaN

Âбþ¤¹¤ëx86 ¤Ç¤Î½ÐÎϤϡ¢¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£

$x
80387 chip is present.
cw      0x137f
sw      0x3920
cssel 0x17  ipoff 0x2d93                datasel 0x1f  dataoff 0x5740
 st[0]  +3.24999988079071044921875 e-1            VALID
 st[1]  +5.6539133243479549034419688 e73          EMPTY
 st[2]  +2.0000000000000008881784197              EMPTY
 st[3]  +1.8073218308070440556016047 e-1          EMPTY
 st[4]  +7.9180300235748291015625 e-1             EMPTY
 st[5]  +4.201639036693904927233234 e-13          EMPTY
 st[6]  +4.201639036693904927233234 e-13          EMPTY
 st[7]  +2.7224999213218694649185636              EMPTY


Ãí -(x86 ¤Î¤ß)cw ¤ÏÀ©¸æ¥ï¡¼¥É¡¢sw ¤Ï¥¹¥Æ¡¼¥¿¥¹¥ï¡¼¥É¤Ç¤¹¡£



[8]ページ先頭

©2009-2025 Movatter.jp