/* In particular, the following test makes sure that the rounding * for %Ra and %Rb is not done on the MPFR number itself (as it * would overflow). Note: it has been reported on comp.std.c that * some C libraries behave differently on %a, but this is a bug. */ static void check_emax_aux (mpfr_exp_t e) { mpfr_t x; char *s1, s2[256]; int i; mpfr_exp_t emax; MPFR_ASSERTN (e <= LONG_MAX); emax = mpfr_get_emax (); set_emax (e); mpfr_init2 (x, 16); mpfr_set_inf (x, 1); mpfr_nextbelow (x); i = mpfr_asprintf (&s1, "%Ra %.2Ra", x, x); MPFR_ASSERTN (i > 0); mpfr_snprintf (s2, 256, "0x7.fff8p+%ld 0x8.00p+%ld", e-3, e-3); if (strcmp (s1, s2) != 0) { printf ("Error in check_emax_aux for emax = "); if (e > LONG_MAX) printf ("(>LONG_MAX)\n"); else printf ("%ld\n", (long) e); printf ("Expected %s\n", s2); printf ("Got %s\n", s1); exit (1); } mpfr_free_str (s1); i = mpfr_asprintf (&s1, "%Rb %.2Rb", x, x); MPFR_ASSERTN (i > 0); mpfr_snprintf (s2, 256, "1.111111111111111p+%ld 1.00p+%ld", e-1, e); if (strcmp (s1, s2) != 0) { printf ("Error in check_emax_aux for emax = "); if (e > LONG_MAX) printf ("(>LONG_MAX)\n"); else printf ("%ld\n", (long) e); printf ("Expected %s\n", s2); printf ("Got %s\n", s1); exit (1); } mpfr_free_str (s1); mpfr_clear (x); set_emax (emax); }
/* 1. compare expected string with the string BUFFER returned by mpfr_sprintf(buffer, fmt, x) 2. then test mpfr_snprintf (buffer, p, fmt, x) with a random p. */ static int check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x) { int n0, n1, p; char buffer[BUF_SIZE]; /* test mpfr_sprintf */ n0 = mpfr_sprintf (buffer, fmt, x); if (strcmp (buffer, expected) != 0) { printf ("Error in mpfr_sprintf (s, \"%s\", x);\n", fmt); printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer); exit (1); } /* test mpfr_snprintf */ p = (int) (randlimb () % n0); if (p == 0 && (randlimb () & 1) == 0) { n1 = mpfr_snprintf (NULL, 0, fmt, x); } else { buffer[p] = 17; n1 = mpfr_snprintf (buffer, p, fmt, x); if (buffer[p] != 17) { printf ("Buffer overflow in mpfr_snprintf for p = %d!\n", p); exit (1); } } if (n0 != n1) { printf ("Error in mpfr_snprintf (s, %d, \"%s\", x) return value\n", p, fmt); printf ("expected: %d\ngot: %d\n", n0, n1); exit (1); } if ((p > 1 && strncmp (expected, buffer, p-1) != 0) || (p == 1 && buffer[0] != '\0')) { char part_expected[BUF_SIZE]; strncpy (part_expected, expected, p); part_expected[p-1] = '\0'; printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n", p, fmt); printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer); exit (1); } return n0; }
const char* MpfrFloat::getAsString(unsigned precision) const { #if(MPFR_VERSION_MAJOR < 2 || (MPFR_VERSION_MAJOR == 2 && MPFR_VERSION_MINOR < 4)) static const char* retval = "[mpfr_snprintf() is not supported in mpfr versions prior to 2.4]"; return retval; #else mpfrFloatString().resize(precision+30); mpfr_snprintf(&(mpfrFloatString()[0]), precision+30, "%.*RNg", precision, mData->mFloat); return &(mpfrFloatString()[0]); #endif }
tree ubsan_instrument_float_cast (location_t loc, tree type, tree expr) { tree expr_type = TREE_TYPE (expr); tree t, tt, fn, min, max; enum machine_mode mode = TYPE_MODE (expr_type); int prec = TYPE_PRECISION (type); bool uns_p = TYPE_UNSIGNED (type); /* Float to integer conversion first truncates toward zero, so even signed char c = 127.875f; is not problematic. Therefore, we should complain only if EXPR is unordered or smaller or equal than TYPE_MIN_VALUE - 1.0 or greater or equal than TYPE_MAX_VALUE + 1.0. */ if (REAL_MODE_FORMAT (mode)->b == 2) { /* For maximum, TYPE_MAX_VALUE might not be representable in EXPR_TYPE, e.g. if TYPE is 64-bit long long and EXPR_TYPE is IEEE single float, but TYPE_MAX_VALUE + 1.0 is either representable or infinity. */ REAL_VALUE_TYPE maxval = dconst1; SET_REAL_EXP (&maxval, REAL_EXP (&maxval) + prec - !uns_p); real_convert (&maxval, mode, &maxval); max = build_real (expr_type, maxval); /* For unsigned, assume -1.0 is always representable. */ if (uns_p) min = build_minus_one_cst (expr_type); else { /* TYPE_MIN_VALUE is generally representable (or -inf), but TYPE_MIN_VALUE - 1.0 might not be. */ REAL_VALUE_TYPE minval = dconstm1, minval2; SET_REAL_EXP (&minval, REAL_EXP (&minval) + prec - 1); real_convert (&minval, mode, &minval); real_arithmetic (&minval2, MINUS_EXPR, &minval, &dconst1); real_convert (&minval2, mode, &minval2); if (real_compare (EQ_EXPR, &minval, &minval2) && !real_isinf (&minval)) { /* If TYPE_MIN_VALUE - 1.0 is not representable and rounds to TYPE_MIN_VALUE, we need to subtract more. As REAL_MODE_FORMAT (mode)->p is the number of base digits, we want to subtract a number that will be 1 << (REAL_MODE_FORMAT (mode)->p - 1) times smaller than minval. */ minval2 = dconst1; gcc_assert (prec > REAL_MODE_FORMAT (mode)->p); SET_REAL_EXP (&minval2, REAL_EXP (&minval2) + prec - 1 - REAL_MODE_FORMAT (mode)->p + 1); real_arithmetic (&minval2, MINUS_EXPR, &minval, &minval2); real_convert (&minval2, mode, &minval2); } min = build_real (expr_type, minval2); } } else if (REAL_MODE_FORMAT (mode)->b == 10) { /* For _Decimal128 up to 34 decimal digits, - sign, dot, e, exponent. */ char buf[64]; mpfr_t m; int p = REAL_MODE_FORMAT (mode)->p; REAL_VALUE_TYPE maxval, minval; /* Use mpfr_snprintf rounding to compute the smallest representable decimal number greater or equal than 1 << (prec - !uns_p). */ mpfr_init2 (m, prec + 2); mpfr_set_ui_2exp (m, 1, prec - !uns_p, GMP_RNDN); mpfr_snprintf (buf, sizeof buf, "%.*RUe", p - 1, m); decimal_real_from_string (&maxval, buf); max = build_real (expr_type, maxval); /* For unsigned, assume -1.0 is always representable. */ if (uns_p) min = build_minus_one_cst (expr_type); else { /* Use mpfr_snprintf rounding to compute the largest representable decimal number less or equal than (-1 << (prec - 1)) - 1. */ mpfr_set_si_2exp (m, -1, prec - 1, GMP_RNDN); mpfr_sub_ui (m, m, 1, GMP_RNDN); mpfr_snprintf (buf, sizeof buf, "%.*RDe", p - 1, m); decimal_real_from_string (&minval, buf); min = build_real (expr_type, minval); } mpfr_clear (m); } else return NULL_TREE; if (flag_sanitize_undefined_trap_on_error) fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0); else { /* Create the __ubsan_handle_float_cast_overflow fn call. */ tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", NULL, NULL, ubsan_type_descriptor (expr_type), ubsan_type_descriptor (type), NULL_TREE); enum built_in_function bcode = flag_sanitize_recover ? BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW : BUILT_IN_UBSAN_HANDLE_FLOAT_CAST_OVERFLOW_ABORT; fn = builtin_decl_explicit (bcode); fn = build_call_expr_loc (loc, fn, 2, build_fold_addr_expr_loc (loc, data), ubsan_encode_value (expr, false)); } t = fold_build2 (UNLE_EXPR, boolean_type_node, expr, min); tt = fold_build2 (UNGE_EXPR, boolean_type_node, expr, max); return fold_build3 (COND_EXPR, void_type_node, fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, tt), fn, integer_zero_node); }
static std::string mpfr_approx(mpfr_t const &f) { char buf[20]; mpfr_snprintf(buf, 20, "%Rg", f); return buf; }
/** * print the object specified by v in the provided buffer. * follows standard snprintf rules, in that it returns the * number of bytes required to print if an insufficient buffer * length is provided. * * if display is true, then the results are printed as human * readable (p_display), otherwise it is printed as machine * readable (p_write) */ int lisp_snprintf(lexec_t *exec, char *buf, int len, lv_t *v, int display) { int pair_len = 0; switch(v->type) { case l_null: return snprintf(buf, len, "()"); case l_int: /* return snprintf(buf, len, "%" PRIu64, L_INT(v)); */ return gmp_snprintf(buf, len, "%Zd", L_INT(v)); case l_rational: return gmp_snprintf(buf, len, "%Qd", L_RAT(v)); case l_float: /* return snprintf(buf, len, "%0.16g", L_FLOAT(v)); */ return mpfr_snprintf(buf, len, "%Rg", L_FLOAT(v)); case l_bool: return snprintf(buf, len, "%s", L_BOOL(v) ? "#t": "#f"); case l_sym: return snprintf(buf, len, "%s", L_SYM(v)); case l_str: if(display) return snprintf(buf, len, "%s", L_STR(v)); else return snprintf(buf, len, "\"%s\"", L_STR(v)); case l_pair: if(len >= 1) sprintf(buf, "("); pair_len += 1; lv_t *vp = v; while(vp && L_CAR(vp)) { pair_len += lisp_snprintf(exec, buf + pair_len, (len - pair_len) > 0 ? len - pair_len : 0, L_CAR(vp), display); if(L_CDR(vp) && (L_CDR(vp)->type != l_pair)) { pair_len += snprintf(buf + pair_len, (len - pair_len) > 0 ? len - pair_len : 0, " . "); pair_len += lisp_snprintf(exec, buf + pair_len, (len - pair_len) > 0 ? len - pair_len : 0, L_CDR(vp), display); vp = NULL; } else { vp = L_CDR(vp); if(vp) { if (len - pair_len > 0) snprintf(buf + pair_len, len - pair_len, " "); pair_len++; } } } if (len - pair_len > 0) { sprintf(buf + pair_len, ")"); } pair_len++; return pair_len; break; case l_fn: rt_assert(!display, le_type, "cannot display function types"); if(L_FN(v) == NULL) return snprintf(buf, len, "<lambda@%p>", v); else return snprintf(buf, len, "<built-in@%p>", v); break; case l_char: if(display) return snprintf(buf, len, "%c", L_CHAR(v)); else return snprintf(buf, len, "#\\x%02x", L_CHAR(v)); break; case l_port: rt_assert(!display, le_type, "cannot display port types"); return snprintf(buf, len, "<port@%p>", v); break; case l_err: rt_assert(!display, le_type, "cannot display error types"); return snprintf(buf, len, "<error@%p:%d>", v, L_ERR(v)); break; default: // missing a type check. assert(0); } }
int Lib_Mpcr_Imag_SnPrintf(char * dest , unsigned int digits, const char *template1, MpcrPtr x) { return mpfr_snprintf(dest, digits, template1, mpc_imagref((mpc_ptr) x)); }
int Lib_Mpcr_Imag_SnPrintf_SizeInBase10(const char *template1, MpcrPtr x) { return mpfr_snprintf(NULL, 0, template1, mpc_imagref((mpc_ptr) x)); }