On Fri, Jul 25, 2008 at 12:36 PM, Andreas Jaeger <aj@xxxxxxxxxx> wrote: > "Michael Kerrisk" <mtk.manpages@xxxxxxxxxxxxxx> writes: > >> Well, for example, according to my tests, cos(3) does not set errno. >> Is that what you would have expected? > > No, I wouldn't. (Slightly confused here, since you seem to contradict my result, but then the text below seems to agree with my result. But maybe I'm just misreading your text.) > And double checking, it's the other way round :-(. We > test the exception handling, not the error handling, so tests like > (libc/math/libm-test.inc) these > > TEST_f_f (cos, plus_infty, nan_value, INVALID_EXCEPTION); > TEST_f_f (cos, minus_infty, nan_value, INVALID_EXCEPTION); > > test that cos with input plus/minus infinity returns a NaN and raises > and invalid exception which is tested with fetestexcept. And if you > have different results, please tell me, When I run the program belwo, this is what I see for a domain error from cos(): $ ./a.out inf errno == 0 fetestexcept() says: 1 FE_INVALID cos(inf)=nan Cheers, Michael /* t_cos.c */ #define _XOPEN_SOURCE 600 #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <fenv.h> #include <math.h> #include <float.h> #include <ctype.h> /* Convert a string to a double, but allow a few special cases in the form of non-numeric strings */ static double strToDouble(char *str) { char *p; char *s; double retval; if (str == NULL) { fprintf(stderr, "Missing argument\n"); exit(EXIT_FAILURE); } s = strdup(str); if (s == NULL) { perror("strdup"); exit(EXIT_FAILURE); } for (p = s; *p; p++) *p = tolower(*p); if (strcmp(s, "-inf") == 0) retval = -HUGE_VAL; else if (strcmp(s, "inf") == 0 || strcmp(s, "+inf") == 0) retval = HUGE_VAL; else if (strcmp(s, "nan") == 0) retval = nan(""); else if (strcmp(s, "dbl_min") == 0) retval = DBL_MIN; else if (strcmp(s, "-dbl_min") == 0) retval = -DBL_MIN; else if (strcmp(s, "dbl_max") == 0) retval = DBL_MAX; else if (strcmp(s, "-dbl_max") == 0) retval = -DBL_MAX; else if (strncmp(s, "subnormal", 9) == 0 || strncmp(s, "-subnormal", 10) == 0) { char *h; int d, j; h = strchr(s, ':'); if (h == NULL) d = 4; else d = atoi(h + 1); printf("subnormal denominator is %d\n", 1 << d); retval = DBL_MIN; for (j = 0; j < d; j++) retval /= 2.0; if (s[0] == '-') retval = -retval; printf("Returning %e\n", retval); } else if (strchr("+-0123456789", s[0]) == NULL) { fprintf(stderr, "Bad argument: %s\n", s); exit(EXIT_FAILURE); } else retval = atof(s); free(s); return retval; } /* strToDouble */ static void clearErrors(void) { errno = 0; feclearexcept(FE_ALL_EXCEPT); } static void checkErrors(void) { int s; if (errno == 0) { fprintf(stderr, "errno == 0\n"); } else { int e = errno; perror("errno"); if (e == EDOM) fprintf(stderr, "errno == EDOM\n"); else if (e == ERANGE) fprintf(stderr, "errno == ERANGE\n"); else fprintf(stderr, "errno == %d\n", e); } s = fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT); printf("fetestexcept() says: %d", s); if (s & FE_INVALID) printf(" FE_INVALID"); if (s & FE_DIVBYZERO) printf(" FE_DIVBYZERO"); if (s & FE_OVERFLOW) printf(" FE_OVERFLOW"); if (s & FE_UNDERFLOW) printf(" FE_UNDERFLOW"); if (s & FE_INEXACT) printf(" FE_INEXACT"); printf("\n"); } int main(int argc, char *argv[]) { double x, r; x = strToDouble(argv[1]); clearErrors(); r = cos(x); checkErrors(); printf("cos(%e)=%e\n", x, r); exit(EXIT_SUCCESS); } /* main */ -- To unsubscribe from this list: send the line "unsubscribe linux-man" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html