¤³¤ÎÉÕÏ¿¤Ç¤Ï¡¢¤è¤¯¹Ô¤ï¤ì¤ëºî¶È¤ÎÎã¤ò¼¨¤·¤Þ¤¹¡£Îã¤Ï FORTRAN¡¢¤ª¤è¤Ó ANSI C ¤Ç½ñ¤«¤ì¤Æ¤ª¤ê¡¢¤½¤Î¿¤¯¤Ï¸½¥Ð¡¼¥¸¥ç¥ó¤Î
libm¤Èlibsunmath¤Ë°Í¸¤·¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤é¤ÎÎã¤Ï¡¢Solaris ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¾å¤Î C ¤ª¤è¤Ó FORTRAN ¥³¥ó¥Ñ¥¤¥é¤Ç¥Æ¥¹¥È¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ÉâÆ°¾®¿ôÅÀ¿ô¤Î 16 ¿Êɽ¸½¤Î¸¡¾ÚÊýË¡¤òÎã¤Ç¼¨¤·¤Þ¤¹¡£³ÊǼ¤µ¤ì¤¿¥Ç¡¼¥¿¤Î 16 ¿Êɽ¸½¤ò¸«¤ë¤Ë¤Ï¡¢¥Ç¥Ð¥Ã¥¬¤ò»ÈÍѤ¹¤ë¤³¤È¤â¤Ç¤¤Þ¤¹¡£
°Ê²¼¤Î C ¤Î¥×¥í¥°¥é¥à¤Ç¤Ï¡¢ÇÜÀºÅ٤ζá»÷Ãͤò ¦Ð ¤ÈñÀºÅÙ¤Î̵¸ÂÂç¤Ë½ÐÎϤ·¤Þ¤¹¡£
SPARC ¤Ç¤Ï¡¢¾åµ¤Î¥×¥í¥°¥é¥à¤Î½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
DP Approx pi = 400921fb 54442d18 = 3.14159265358979312e+00Single Precision Infinity : 7f800000¼¡¤Î FORTRAN ¥×¥í¥°¥é¥à¤Ï¡¢ºÇ¾®¤ÎÀµµ¬¿ô¤ò¤½¤ì¤¾¤ì¤Î·Á¼°¤Ç½ÐÎϤ·¤Þ¤¹¡£
SPARC ¤Ç¤Ï¡¢Âбþ¤¹¤ë½ÐÎϤ¬¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
(x86 ¤Ç¤Ï¡¢FORTRAN ¥³¥ó¥Ñ¥¤¥é¤Ï
real*16·¿¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤»¤ó¡£Á°µ¤ÎÎã¤ò x86 ¤Ç¼Â¹Ô¤¹¤ë¾ì¹ç¤Ï¡¢real*16Àë¸À¤È¡¢4 ÇÜÀºÅÙ¤ÎÃͤη׻»¤È½ÐÎϤò¹Ô¤¦¥³¡¼¥É¤òºï½ü¤·¤Æ¤¯¤À¤µ¤¤¡£)¤³¤ÎÀá¤Ç¤Ï¡¢¿ô³Ø¥é¥¤¥Ö¥é¥ê¤Î´Ø¿ô¤ò»ÈÍѤ·¤¿Îã¤ò¼¨¤·¤Þ¤¹¡£
¼¡¤ÎÎã¤Ç¤Ï¡¢¿ô¤ÎÇÛÎó¤òÀ¸À®¤¹¤ëÍð¿ô´Ø¿ô¤ò¸Æ¤Ó½Ð¤·¡¢Í¿¤¨¤é¤ì¤¿¿ô¤Î
EXP¤ò·×»»¤¹¤ë¤Î¤Ë¤«¤«¤ë»þ´Ö¤ò¬Äꤹ¤ë´Ø¿ô¤ò»ÈÍѤ·¤Þ¤¹¡£Á°µ¤ÎÎã¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤Ë¤Ï¡¢¥³¥ó¥Ñ¥¤¥é¤¬¼«Æ°Åª¤Ë¥×¥ê¥×¥í¥»¥Ã¥µ¤ò¸Æ¤Ó½Ð¤¹¤è¤¦¤Ë¥½¡¼¥¹¥³¡¼¥É¤òÀÜÈø¼
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, i1format(' 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) x3format(' Starting from ', 1PE23.16E3, - ', the next representable number ') write(*,4) direction, y4format(' 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, y5format(' 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.5The sign bit of -5.5000000000000 is 1Starting from 4.9406564584124654-324, the next representablenumber towards -Inf is 0.0000000000000000E+000Starting from 4.9406564584124654-324, the next representablenumber towards 1.0 is 9.8813129168249309-324Scaling 2.0 by 2**3 is 16.0SINGLE PRECISION EXAMPLES:The base 2 exponent of 32.0 is 5The sign bit of -5.50000 is 1-5.5 was given the sign of 12.4 and is now 5.5Starting from 1.4012984643248171E-045, the next representablenumber towards -Inf is 0.0000000000000000E+000Starting from 1.4012984643248171E-045, the next representablenumber towards 1.0 is 2.8025969286496341E-045Scaling 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 ffffffffnextafter(max_subnormal,0) = 2.2250738585072004e-308= 000fffff fffffffesingle precision min subnormal = 1.40129846e-45 = 00000001x86 ¥¢¡¼¥¥Æ¥¯¥Á¥ã¤Ï¡Ö¥ê¥È¥ë¥¨¥ó¥Ç¥£¥¢¥ó¡×¤Ç¤¢¤ë¤¿¤á¡¢x86 ¤Ç¤Î½ÐÎϤϾ¯¡¹°Û¤Ê¤ê¤Þ¤¹ (ÇÜÀºÅÙ¿ô¤Î 16 ¿Êɽ¸½¤Ç¾å°Ì¤È²¼°Ì¤Î¥ï¡¼¥É¤¬µÕ¤Ë¤Ê¤ê¤Þ¤¹)¡£
quiet NaN: NaN = ffffffff 7fffffffnextafter(max_subnormal,0) = 2.2250738585072004e-308= fffffffe 000fffffsingle precision min subnormal = 1.40129846e-45 = 00000001
ieee_values´Ø¿ô¤ò»ÈÍѤ¹¤ë FORTRAN ¥×¥í¥°¥é¥à¤Ç¤Ï¡¢´Ø¿ô¤Î·¿¤òÀë¸À¤¹¤ë¤è¤¦¤ËÃí°Õ¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£
program print_ieee_valuescc implicit ʸ¤Ï¡¢f77_floatingpoint ¤Îµ¿»÷ÁȤ߹þ¤ß´Ø¿ô¤¬¡¢c Àµ¤·¤¤·¿¤ÇÀë¸À¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò³Îǧ¤·¤Þ¤¹¡£cimplicit real*16 (q)implicit double precision (d)implicit real (r)real*16 z, zero, onedouble precision xreal rczero = 0.0one = 1.0z = q_nextafter(zero, one)x = d_infinity()r = r_max_normal()cprint *, zprint *, xprint *, rcendSPARC ¤Ç¤Ï¡¢½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
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 -lmdemo%a.outWith rounding direction nearest,sqrt(.5) = 0x3fe6a09e 0x667f3bcd = 7.071067811865476e-01With rounding direction tozero,sqrt(.5) = 0x3fe6a09e 0x667f3bcc = 7.071067811865475e-01demo%x86 ¤Ç¤Ï¡¢¤³¤Îû¤¤¥×¥í¥°¥é¥à¤Î½ÐÎϤϡ¢¥¼¥íÀÚ¤ê¼Î¤Æ¥â¡¼¥É¤Î¸ú²Ì¤ò¼¨¤·¤Þ¤¹¡£
demo%cc rounding_direction.c -lmdemo%a.outWith rounding direction nearest,sqrt(.5) = 0x667f3bcd 0x3fe6a09e = 7.071067811865476e-01With rounding direction tozero,sqrt(.5) = 0x667f3bcc 0x3fe6a09e = 7.071067811865475e-01demo%FORTRAN ¥×¥í¥°¥é¥à¤Ç¥¼¥íÀÚ¤ê¼Î¤Æ¥â¡¼¥É¤òÀßÄꤷ¤Þ¤¹¡£
program ieee_flags_democharacter*16 outi = 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: ", outend
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 -lmdemo%a.outFloating point underflow at 0x000153a8 __d_lcrans_, nonstop mode0x000153b4 __d_lcrans_0x00011594 mainFloating point underflow at 0x00011244 norm, nonstop mode0x00011248 norm0x000115b4 mainnorm: 1.32533e-307Floating point overflow at 0x00011244 norm, nonstop mode0x00011248 norm0x00011660 mainnorm: 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 bits53 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.outx = 1.11254e-308Highest priority exception is: underflow0 0 0 1 1Inexact; Underflow;See the Numerical Computation Guide, ieee_flags(3M)[ÆüËܸìÌõ]Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤¬È¯À¸¤·¤Þ¤·¤¿:ÉÔÀµ³Î¡¢¥¢¥ó¥À¡¼¥Õ¥í¡¼¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_flagsFORTRAN ¤Ç¤âƱ¤¸¤³¤È¤¬¹Ô¤¨¤Þ¤¹¡£
/*¤³¤ì¤Ï¡¢¼¡¤Î¤è¤¦¤ÊFORTRAN¥×¥í¥°¥é¥àÎ㠤Ǥ¹¡§* ¥¢¥ó¥À¡¼¥Õ¥í¡¼Îã³°¤òȯÀ¸¤µ¤»¤ë*ieee_flags¤ò»ÈÍѤ·¤Æ¡¢¤É¤ÎÎã³°¤¬È¯À¸¤·¤¿¤«¤òȽÄꤹ¤ë*ieee_flags¤¬ÊÖ¤¹À°¿ôÃͤò²òÆÉ¤¹¤ë* ̤½èÍý¤ÎÎã³°¤ò¤¹¤Ù¤Æ¥¯¥ê¥¢¤Ë¤¹¤ëC ¤Î¥×¥ê¥×¥í¥»¥Ã¥µ¤¬µ¯Æ°¤µ¤ì¡¢¥Ø¥Ã¥À¡¼¥Õ¥¡¥¤¥ëf77_floatingpoint.h¤¬¼è¤ê¹þ¤Þ¤ì¤ë¤è¤¦¤Ë¤¹¤ë¤¿¤á¤Ë¡¢¤³¤Î¥×¥í¥°¥é¥à¤ÏÀÜÈø¼.F¤Î¥Õ¥¡¥¤¥ë¤ËÊݸ¤·¤Æ¤¯¤À¤µ¤¤¡£*/#include <f77_floatingpoint.h>program decode_accrued_exceptionsdouble precision xinteger accrued, inx, div, under, over, invcharacter*16 outdouble precision d_max_subnormalc ¥¢¥ó¥À¡¼¥Õ¥í¡¼Îã³°¤òȯÀ¸¤µ¤»¤ëx = d_max_subnormal() / 2.0c ¤É¤ÎÎã³°¤¬È¯À¸¤·¤¿¤«¤òȽÄꤹ¤ë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 ", outc1¤ÏÎã³°¤¬È¯À¸¤·¤¿¤³¤È¤ò¼¨¤·¡¢0¤ÏÎã³°¤¬È¯À¸¤·¤Æ¤¤¤Ê¤¤¤³¤È¤ò¼¨¤¹print *, inv, over, div, under, inxc ̤½èÍý¤ÎÎã³°¤ò¤¹¤Ù¤Æ¥¯¥ê¥¢¤Ë¤¹¤ëi = ieee_flags('clear', 'exception', 'all', out)end¤³¤Î FORTRAN ¥×¥í¥°¥é¥à¤Î½ÐÎϤǤ¹¡£
Highest priority exception is underflow0 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: 2x86 ¤Ç¤Ï¡¢½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
out is: division , fp exception code is: 4
Ãí -°Ê²¼¤ÎÎã¤Ï¡¢Solaris ¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°´Ä¶¤À¤±¤ËŬÍѤǤ¤Þ¤¹¡£SPARC ¤Ç¤Ï¡¢Îã³°¤òÆÃÄꤹ¤ë¤¿¤á¤Î¥·¥°¥Ê¥ë¥Ï¥ó¥É¥é¤òÀßÄꤹ¤ë FORTRAN ¤ª¤è¤Ó C ¥×¥í¥°¥é¥à¤ÎÎã¤ò¼¨¤·¤Þ¤¹¡£
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, addr77 format ('floating-point exception code ', i2, ',', * a17, ',', ' at address ', z8 ) end
d_min_normal() / 13.0 = 1.7115952757748-309floating-point exception code 4, overflow , at address 1131C1.0d300*1.0d300 = 1.0000000000000+300Inexact; Underflow;IEEE floating-point exception traps enabled:overflow; division by zero; invalid operation;[ÆüËܸìÌõ]Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤¬È¯À¸¤·¤Þ¤·¤¿:ÉÔÀµ³Î¡¢¥¢¥ó¥À¡¼¥Õ¥í¡¼°Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤Î¥È¥é¥Ã¥×¤¬Í¸ú¤Ç¤¹:¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¡¢¥¼¥í¤Ë¤è¤ë½ü»»¡¢Ìµ¸ú¤Ê±é»»¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_flagsieee_handler
/* * 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.5signal 8, sigfpe code 7: invalid exception at address 10da82. Div0: 1.0 / 0.0signal 8, sigfpe code 3: division exception at address 10e443. Overflow: -max_normal() - 1.0e294signal 8, sigfpe code 4: overflow exception at address 10ee84. Underflow: min_normal() * min_normal()signal 8, sigfpe code 5: underflow exception at address 10f805. Inexact: 2.0 / 3.0signal 8, sigfpe code 6: inexact exception at address 1106c6. Inexact trapping disabled; 2.0 / 3.0Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤¬È¯À¸¤·¤Þ¤·¤¿:ÉÔÀµ³Î¡¢¥¢¥ó¥À¡¼¥Õ¥í¡¼°Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤Î¥È¥é¥Ã¥×¤¬Í¸ú¤Ç¤¹:¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¡¢¥¼¥í¤Ë¤è¤ë½ü»»¡¢Ìµ¸ú¤Ê±é»»¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_flagsieee_handlerSPARC ¤Ç¤Ï¡¢¼¡¤Î¥×¥í¥°¥é¥à¤Ï¡¢¤¢¤ëÎã³°¤Î¾õ¶·¤«¤éµ¯¤¤¿¥Ç¥Õ¥©¥ë¥È·ë²Ì¤ò½¤Àµ¤¹¤ë¤¿¤á¤Î
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+308single precision division: 1/0 = 3.40282e+38division by zero;See the Numerical Computation Guide, ieee_handler(3M)[ÆüËܸìÌõ]Ãí: °Ê²¼¤Î IEEE ÉâÆ°¾®¿ôÅÀÎã³°¤Î¥È¥é¥Ã¥×¤¬Í¸ú¤Ç¤¹:¥¼¥í¤Ë¤è¤ë½ü»»¾ÜºÙ¤Ï¡¢¡Ø¿ôÃÍ·×»»¥¬¥¤¥É¡Ù¤Îieee_handlerÆÃÄê¤ÎÉâÆ°¾®¿ôÅÀÎã³°¤Î¾ì¹ç¡¢
ieee_handler¤ò»ÈÍѤ·¤Æ¶¯À©Åª¤Ë¥×¥í¥°¥é¥à¤ò°Û¾ï½ªÎ»¤µ¤»¤ë¤³¤È¤¬¤Ç¤¤Þ¤¹¡£
#include <f77_floatingpoint.h>program abortcieeer = ieee_handler('set', 'division', SIGFPE_ABORT)if (ieeer .ne. 0) print *, ' ieee trapping not supported'r = 14.2s = 0.0r = r/scprint *, 'you should not see this; system should abort'cend¤³¤ÎÀá¤Ç¤Ï¡¢
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.1818f(-4) = -1.87302, f'(-4) = -0.428193Floating point division by zero at 0x08048dbe continued_fraction, nonstop mode0x08048dc1 continued_fraction0x08048eda mainFloating point invalid operation (inf/inf) at 0x08048dcf continued_fraction, handler: handler0x08048dd2 continued_fraction0x08048eda mainFloating point invalid operation (0*inf) at 0x08048dd2 continued_fraction, handler: handler0x08048dd8 continued_fraction0x08048eda mainf(-3) = -3, f'(-3) = -3.16667f(-2) = -4.44089e-16, f'(-2) = -3.41667f(-1) = -1.22222, f'(-1) = -0.444444f( 0) = -1.33333, f'( 0) = 0.203704f( 1) = -1, f'( 1) = 0.333333f( 2) = -0.777778, f'( 2) = 0.12037f( 3) = -0.714286, f'( 3) = 0.0272109f( 4) = -0.666667, f'( 4) = 0.203704f( 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 do1 format('f(', I2, ') = ', G12.6, ', f''(', I2, ') = ', G12.6) end¤³¤Î¥×¥í¥°¥é¥à¤Î½ÐÎϤϼ¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
f(-5) = -1.59649 , f'(-5) = -.181800f(-4) = -1.87302 , f'(-4) = -.428193f(-3) = -3.00000 , f'(-3) = -3.16667f(-2) = -.444089E-15, f'(-2) = -3.41667f(-1) = -1.22222 , f'(-1) = -.444444f( 0) = -1.33333 , f'( 0) = 0.203704f( 1) = -1.00000 , f'( 1) = 0.333333f( 2) = -.777778 , f'( 2) = 0.120370f( 3) = -.714286 , f'( 3) = 0.272109E-01f( 4) = -.666667 , f'( 4) = 0.203704f( 5) = -.777778 , f'( 5) = 0.185185E-01Note: 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,4do 20 j = 1,3print *, ' array[', i, '][', j, '] = ', array(i,j)20 continueprint *10 continuereturnendreal function demo_two(number)real numberdemo_two = sin(number)returnenddouble precision function demo_three(number)double precision numberdemo_three = sin(number)returnend¤½¤ì¤«¤é¡¢¥³¥ó¥Ñ¥¤¥ë¤È¥ê¥ó¥¯¤ò¹Ô¤¤¤Þ¤¹¡£
cc -c driver.cf77 -c drivee.fdemo_one:demo_two:demo_three:f77 -o driver driver.o drivee.o
from the fortran routine:array[ 1][ 1] = 0.array[ 1][ 2] = 1.0000000000000array[ 1][ 3] = 2.0000000000000array[ 2][ 1] = 2.0000000000000array[ 2][ 2] = 3.0000000000000array[ 2][ 3] = 4.0000000000000array[ 3][ 1] = 4.0000000000000array[ 3][ 2] = 5.0000000000000array[ 3][ 3] = 6.0000000000000array[ 4][ 1] = 6.0000000000000array[ 4][ 2] = 7.0000000000000array[ 4][ 3] = 8.0000000000000from the driverarray[0][0] = 0.000000e+00array[0][1] = 2.000000e+00array[0][2] = 4.000000e+00array[0][3] = 6.000000e+00array[1][0] = 1.000000e+00array[1][1] = 3.000000e+00array[1][2] = 5.000000e+00array[1][3] = 7.000000e+00array[2][0] = 2.000000e+00array[2][1] = 4.000000e+00array[2][2] = 6.000000e+00array[2][3] = 8.000000e+00f = sin(g) from a single precision fortran functionf, g: 9.9749500e-01, 1.5000000e+00x = sin(y) from a double precision fortran functionx, 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=fIEEE ÇÜÀºÅÙ 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=Xf0¤ËñÀºÅÙ 1.0 ¤òÀßÄêassign $f0=1.03f800000>f0f0/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:b2 ÈÖÌܤÎÊýË¡¤Ç¤Ï¡¢ ¤ËÂбþ¤·¤Æ¤¤¤ë¥³¡¼¥ÉÉô¤ÎÀèÆ¬¤ËÁêÅö¤¹¤ëÀäÂÐ¥¢¥É¥ì¥¹¤òÄ´¤Ù¤¿¸å¡¢¤½¤ÎÀäÂÐ¥¢¥É¥ì¥¹¤Ë¥Ö¥ì¡¼¥¯¤òÀßÄꤷ¤Þ¤¹¡£
myfunction=X23a823a8: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(ÉâÆ°¾®¿ôÅÀ¥¹¥Æ¡¼¥¿¥¹¥ì¥¸¥¹¥¿) ¤âɽ¼¨¤·¤Æ¤¤¤Þ¤¹¡£
$xfsr 40020f0400921fb +2.1426990e+00f154442d18 +3.3702806e+12 +3.1415926535897931e+00f2 2 +2.8025969e-45f3 0 +0.0000000e+00 +4.2439915819305446e-314f440000000 +2.0000000e+00f5 0 +0.0000000e+00 +2.0000000000000000e+00f63de0b460 +1.0971904e-01f7 0 +0.0000000e+00 +1.2154188766544394e-10f83de0b460 +1.0971904e-01f9 0 +0.0000000e+00 +1.2154188766544394e-10f107ff00000 +NaNf11 0 +0.0000000e+00 +Infinityf12ffffffff -NaNf13ffffffff -NaN -NaNf14ffffffff -NaNf15ffffffff -NaN -NaNÂбþ¤¹¤ëx86 ¤Ç¤Î½ÐÎϤϡ¢¼¡¤Î¤È¤ª¤ê¤Ç¤¹¡£
$x80387 chip is present.cw 0x137fsw 0x3920cssel 0x17 ipoff 0x2d93 datasel 0x1f dataoff 0x5740st[0] +3.24999988079071044921875 e-1 VALIDst[1] +5.6539133243479549034419688 e73 EMPTYst[2] +2.0000000000000008881784197 EMPTYst[3] +1.8073218308070440556016047 e-1 EMPTYst[4] +7.9180300235748291015625 e-1 EMPTYst[5] +4.201639036693904927233234 e-13 EMPTYst[6] +4.201639036693904927233234 e-13 EMPTYst[7] +2.7224999213218694649185636 EMPTY
Ãí -(x86 ¤Î¤ß)cw¤ÏÀ©¸æ¥ï¡¼¥É¡¢sw¤Ï¥¹¥Æ¡¼¥¿¥¹¥ï¡¼¥É¤Ç¤¹¡£