示例#1
0
/* We should cache the coefficients with the ctm.... */
int
gx_matrix_to_fixed_coeff(const gs_matrix * pmat, register fixed_coeff * pfc,
			 int max_bits)
{
    gs_matrix ctm;
    int scale = -10000;
    int expt, shift;

    ctm = *pmat;
    pfc->skewed = 0;
    if (!is_fzero(ctm.xx)) {
	discard(frexp(ctm.xx, &scale));
    }
    if (!is_fzero(ctm.xy)) {
	discard(frexp(ctm.xy, &expt));
	if (expt > scale)
	    scale = expt;
	pfc->skewed = 1;
    }
    if (!is_fzero(ctm.yx)) {
	discard(frexp(ctm.yx, &expt));
	if (expt > scale)
	    scale = expt;
	pfc->skewed = 1;
    }
    if (!is_fzero(ctm.yy)) {
	discard(frexp(ctm.yy, &expt));
	if (expt > scale)
	    scale = expt;
    }
    /*
     * There are two multiplications in fixed_coeff_mult: one involves a
     * factor that may have max_bits significant bits, the other may have
     * fixed_fraction_bits (_fixed_shift) bits.  Ensure that neither one
     * will overflow.
     */
    if (max_bits < fixed_fraction_bits)
	max_bits = fixed_fraction_bits;
    scale = sizeof(long) * 8 - 1 - max_bits - scale;

    shift = scale - _fixed_shift;
    if (shift > 0) {
	pfc->shift = shift;
	pfc->round = (fixed) 1 << (shift - 1);
    } else {
	pfc->shift = 0;
	pfc->round = 0;
	scale -= shift;
    }
#define SET_C(c)\
  if ( is_fzero(ctm.c) ) pfc->c = 0;\
  else pfc->c = (long)ldexp(ctm.c, scale)
    SET_C(xx);
    SET_C(xy);
    SET_C(yx);
    SET_C(yy);
#undef SET_C
#ifdef DEBUG
    if (gs_debug_c('x')) {
	dlprintf6("[x]ctm: [%6g %6g %6g %6g %6g %6g]\n",
		  ctm.xx, ctm.xy, ctm.yx, ctm.yy, ctm.tx, ctm.ty);
	dlprintf6("   scale=%d fc: [0x%lx 0x%lx 0x%lx 0x%lx] shift=%d\n",
		  scale, pfc->xx, pfc->xy, pfc->yx, pfc->yy,
		  pfc->shift);
    }
#endif
    pfc->max_bits = max_bits;
    return 0;
}
示例#2
0
文件: sprintf.c 项目: fi8on/ruby
VALUE
rb_str_format(int argc, const VALUE *argv, VALUE fmt)
{
    rb_encoding *enc;
    const char *p, *end;
    char *buf;
    long blen, bsiz;
    VALUE result;

    long scanned = 0;
    int coderange = ENC_CODERANGE_7BIT;
    int width, prec, flags = FNONE;
    int nextarg = 1;
    int posarg = 0;
    int tainted = 0;
    VALUE nextvalue;
    VALUE tmp;
    VALUE str;
    volatile VALUE hash = Qundef;

#define CHECK_FOR_WIDTH(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "width given twice");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "width after precision"); \
    }
#define CHECK_FOR_FLAGS(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "flag after width");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "flag after precision"); \
    }

    ++argc;
    --argv;
    if (OBJ_TAINTED(fmt)) tainted = 1;
    StringValue(fmt);
    enc = rb_enc_get(fmt);
    fmt = rb_str_new4(fmt);
    p = RSTRING_PTR(fmt);
    end = p + RSTRING_LEN(fmt);
    blen = 0;
    bsiz = 120;
    result = rb_str_buf_new(bsiz);
    rb_enc_copy(result, fmt);
    buf = RSTRING_PTR(result);
    memset(buf, 0, bsiz);
    ENC_CODERANGE_SET(result, coderange);

    for (; p < end; p++) {
	const char *t;
	int n;
	ID id = 0;

	for (t = p; t < end && *t != '%'; t++) ;
	PUSH(p, t - p);
	if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
	    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &coderange);
	    ENC_CODERANGE_SET(result, coderange);
	}
	if (t >= end) {
	    /* end of fmt string */
	    goto sprint_exit;
	}
	p = t + 1;		/* skip `%' */

	width = prec = -1;
	nextvalue = Qundef;
      retry:
	switch (*p) {
	  default:
	    if (rb_enc_isprint(*p, enc))
		rb_raise(rb_eArgError, "malformed format string - %%%c", *p);
	    else
		rb_raise(rb_eArgError, "malformed format string");
	    break;

	  case ' ':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSPACE;
	    p++;
	    goto retry;

	  case '#':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSHARP;
	    p++;
	    goto retry;

	  case '+':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FPLUS;
	    p++;
	    goto retry;

	  case '-':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FMINUS;
	    p++;
	    goto retry;

	  case '0':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FZERO;
	    p++;
	    goto retry;

	  case '1': case '2': case '3': case '4':
	  case '5': case '6': case '7': case '8': case '9':
	    n = 0;
	    GETNUM(n, width);
	    if (*p == '$') {
		if (nextvalue != Qundef) {
		    rb_raise(rb_eArgError, "value given twice - %d$", n);
		}
		nextvalue = GETPOSARG(n);
		p++;
		goto retry;
	    }
	    CHECK_FOR_WIDTH(flags);
	    width = n;
	    flags |= FWIDTH;
	    goto retry;

	  case '<':
	  case '{':
	    {
		const char *start = p;
		char term = (*p == '<') ? '>' : '}';

		for (; p < end && *p != term; ) {
		    p += rb_enc_mbclen(p, end, enc);
		}
		if (p >= end) {
		    rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
		}
		if (id) {
		    rb_raise(rb_eArgError, "name%.*s after <%s>",
			     (int)(p - start + 1), start, rb_id2name(id));
		}
		id = rb_intern3(start + 1, p - start - 1, enc);
		nextvalue = GETNAMEARG(ID2SYM(id), start, (int)(p - start + 1));
		if (nextvalue == Qundef) {
		    rb_raise(rb_eKeyError, "key%.*s not found", (int)(p - start + 1), start);
		}
		if (term == '}') goto format_s;
		p++;
		goto retry;
	    }

	  case '*':
	    CHECK_FOR_WIDTH(flags);
	    flags |= FWIDTH;
	    GETASTER(width);
	    if (width < 0) {
		flags |= FMINUS;
		width = -width;
	    }
	    p++;
	    goto retry;

	  case '.':
	    if (flags & FPREC0) {
		rb_raise(rb_eArgError, "precision given twice");
	    }
	    flags |= FPREC|FPREC0;

	    prec = 0;
	    p++;
	    if (*p == '*') {
		GETASTER(prec);
		if (prec < 0) {	/* ignore negative precision */
		    flags &= ~FPREC;
		}
		p++;
		goto retry;
	    }

	    GETNUM(prec, precision);
	    goto retry;

	  case '\n':
	  case '\0':
	    p--;
	  case '%':
	    if (flags != FNONE) {
		rb_raise(rb_eArgError, "invalid format character - %%");
	    }
	    PUSH("%", 1);
	    break;

	  case 'c':
	    {
		VALUE val = GETARG();
		VALUE tmp;
		unsigned int c;
		int n;

		tmp = rb_check_string_type(val);
		if (!NIL_P(tmp)) {
		    if (rb_enc_strlen(RSTRING_PTR(tmp),RSTRING_END(tmp),enc) != 1) {
			rb_raise(rb_eArgError, "%%c requires a character");
		    }
		    c = rb_enc_codepoint_len(RSTRING_PTR(tmp), RSTRING_END(tmp), &n, enc);
		}
		else {
		    c = NUM2INT(val);
		    n = rb_enc_codelen(c, enc);
		}
		if (n <= 0) {
		    rb_raise(rb_eArgError, "invalid character");
		}
		if (!(flags & FWIDTH)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
		else if ((flags & FMINUS)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		    FILL(' ', width-1);
		}
		else {
		    FILL(' ', width-1);
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
	    }
	    break;

	  case 's':
	  case 'p':
	  format_s:
	    {
		VALUE arg = GETARG();
		long len, slen;

		if (*p == 'p') arg = rb_inspect(arg);
		str = rb_obj_as_string(arg);
		if (OBJ_TAINTED(str)) tainted = 1;
		len = RSTRING_LEN(str);
		rb_str_set_len(result, blen);
		if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
		    int cr = coderange;
		    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr);
		    ENC_CODERANGE_SET(result,
				      (cr == ENC_CODERANGE_UNKNOWN ?
				       ENC_CODERANGE_BROKEN : (coderange = cr)));
		}
		enc = rb_enc_check(result, str);
		if (flags&(FPREC|FWIDTH)) {
		    slen = rb_enc_strlen(RSTRING_PTR(str),RSTRING_END(str),enc);
		    if (slen < 0) {
			rb_raise(rb_eArgError, "invalid mbstring sequence");
		    }
		    if ((flags&FPREC) && (prec < slen)) {
			char *p = rb_enc_nth(RSTRING_PTR(str), RSTRING_END(str),
					     prec, enc);
			slen = prec;
			len = p - RSTRING_PTR(str);
		    }
		    /* need to adjust multi-byte string pos */
		    if ((flags&FWIDTH) && (width > slen)) {
			width -= (int)slen;
			if (!(flags&FMINUS)) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			CHECK(len);
			memcpy(&buf[blen], RSTRING_PTR(str), len);
			blen += len;
			if (flags&FMINUS) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			rb_enc_associate(result, enc);
			break;
		    }
		}
		PUSH(RSTRING_PTR(str), len);
		rb_enc_associate(result, enc);
	    }
	    break;

	  case 'd':
	  case 'i':
	  case 'o':
	  case 'x':
	  case 'X':
	  case 'b':
	  case 'B':
	  case 'u':
	    {
		volatile VALUE tmp1;
		volatile VALUE val = GETARG();
		char fbuf[32], nbuf[64], *s;
		const char *prefix = 0;
		int sign = 0, dots = 0;
		char sc = 0;
		long v = 0;
		int base, bignum = 0;
		int len;

		switch (*p) {
		  case 'd':
		  case 'i':
		  case 'u':
		    sign = 1; break;
		  case 'o':
		  case 'x':
		  case 'X':
		  case 'b':
		  case 'B':
		    if (flags&(FPLUS|FSPACE)) sign = 1;
		    break;
		}
		if (flags & FSHARP) {
		    switch (*p) {
		      case 'o':
			prefix = "0"; break;
		      case 'x':
			prefix = "0x"; break;
		      case 'X':
			prefix = "0X"; break;
		      case 'b':
			prefix = "0b"; break;
		      case 'B':
			prefix = "0B"; break;
		    }
		}

	      bin_retry:
		switch (TYPE(val)) {
		  case T_FLOAT:
		    if (FIXABLE(RFLOAT_VALUE(val))) {
			val = LONG2FIX((long)RFLOAT_VALUE(val));
			goto bin_retry;
		    }
		    val = rb_dbl2big(RFLOAT_VALUE(val));
		    if (FIXNUM_P(val)) goto bin_retry;
		    bignum = 1;
		    break;
		  case T_STRING:
		    val = rb_str_to_inum(val, 0, TRUE);
		    goto bin_retry;
		  case T_BIGNUM:
		    bignum = 1;
		    break;
		  case T_FIXNUM:
		    v = FIX2LONG(val);
		    break;
		  default:
		    val = rb_Integer(val);
		    goto bin_retry;
		}

		switch (*p) {
		  case 'o':
		    base = 8; break;
		  case 'x':
		  case 'X':
		    base = 16; break;
		  case 'b':
		  case 'B':
		    base = 2; break;
		  case 'u':
		  case 'd':
		  case 'i':
		  default:
		    base = 10; break;
		}

		if (!bignum) {
		    if (base == 2) {
			val = rb_int2big(v);
			goto bin_retry;
		    }
		    if (sign) {
			char c = *p;
			if (c == 'i') c = 'd'; /* %d and %i are identical */
			if (v < 0) {
			    v = -v;
			    sc = '-';
			    width--;
			}
			else if (flags & FPLUS) {
			    sc = '+';
			    width--;
			}
			else if (flags & FSPACE) {
			    sc = ' ';
			    width--;
			}
			snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
			snprintf(nbuf, sizeof(nbuf), fbuf, v);
			s = nbuf;
		    }
		    else {
			s = nbuf;
			if (v < 0) {
			    dots = 1;
			}
			snprintf(fbuf, sizeof(fbuf), "%%l%c", *p == 'X' ? 'x' : *p);
			snprintf(++s, sizeof(nbuf) - 1, fbuf, v);
			if (v < 0) {
			    char d = 0;

			    s = remove_sign_bits(s, base);
			    switch (base) {
			      case 16:
				d = 'f'; break;
			      case 8:
				d = '7'; break;
			    }
			    if (d && *s != d) {
				*--s = d;
			    }
			}
		    }
		    len = (int)strlen(s);
		}
		else {
		    if (sign) {
			tmp = rb_big2str(val, base);
			s = RSTRING_PTR(tmp);
			if (s[0] == '-') {
			    s++;
			    sc = '-';
			    width--;
			}
			else if (flags & FPLUS) {
			    sc = '+';
			    width--;
			}
			else if (flags & FSPACE) {
			    sc = ' ';
			    width--;
			}
		    }
		    else {
			if (!RBIGNUM_SIGN(val)) {
			    val = rb_big_clone(val);
			    rb_big_2comp(val);
			}
			tmp1 = tmp = rb_big2str0(val, base, RBIGNUM_SIGN(val));
			s = RSTRING_PTR(tmp);
			if (*s == '-') {
			    dots = 1;
			    if (base == 10) {
				rb_warning("negative number for %%u specifier");
			    }
			    s = remove_sign_bits(++s, base);
			    switch (base) {
			      case 16:
				if (s[0] != 'f') *--s = 'f'; break;
			      case 8:
				if (s[0] != '7') *--s = '7'; break;
			      case 2:
				if (s[0] != '1') *--s = '1'; break;
			    }
			}
		    }
		    len = rb_long2int(RSTRING_END(tmp) - s);
		}

		if (dots) {
		    prec -= 2;
		    width -= 2;
		}

		if (*p == 'X') {
		    char *pp = s;
		    int c;
		    while ((c = (int)(unsigned char)*pp) != 0) {
			*pp = rb_enc_toupper(c, enc);
			pp++;
		    }
		}
		if (prefix && !prefix[1]) { /* octal */
		    if (dots) {
			prefix = 0;
		    }
		    else if (len == 1 && *s == '0') {
			len = 0;
			if (flags & FPREC) prec--;
		    }
		    else if ((flags & FPREC) && (prec > len)) {
			prefix = 0;
		    }
		}
		else if (len == 1 && *s == '0') {
		    prefix = 0;
		}
		if (prefix) {
		    width -= (int)strlen(prefix);
		}
		if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
		    prec = width;
		    width = 0;
		}
		else {
		    if (prec < len) {
			if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
			prec = len;
		    }
		    width -= prec;
		}
		if (!(flags&FMINUS)) {
		    CHECK(width);
		    while (width-- > 0) {
			buf[blen++] = ' ';
		    }
		}
		if (sc) PUSH(&sc, 1);
		if (prefix) {
		    int plen = (int)strlen(prefix);
		    PUSH(prefix, plen);
		}
		CHECK(prec - len);
		if (dots) PUSH("..", 2);
		if (!bignum && v < 0) {
		    char c = sign_bits(base, p);
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		else if ((flags & (FMINUS|FPREC)) != FMINUS) {
		    char c;

		    if (!sign && bignum && !RBIGNUM_SIGN(val))
			c = sign_bits(base, p);
		    else
			c = '0';
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		PUSH(s, len);
		CHECK(width);
		while (width-- > 0) {
		    buf[blen++] = ' ';
		}
	    }
	    break;

	  case 'f':
	  case 'g':
	  case 'G':
	  case 'e':
	  case 'E':
	  case 'a':
	  case 'A':
	    {
		VALUE val = GETARG();
		double fval;
		int i, need = 6;
		char fbuf[32];

		fval = RFLOAT_VALUE(rb_Float(val));
		if (isnan(fval) || isinf(fval)) {
		    const char *expr;

		    if (isnan(fval)) {
			expr = "NaN";
		    }
		    else {
			expr = "Inf";
		    }
		    need = (int)strlen(expr);
		    if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
			need++;
		    if ((flags & FWIDTH) && need < width)
			need = width;

		    CHECK(need + 1);
		    snprintf(&buf[blen], need + 1, "%*s", need, "");
		    if (flags & FMINUS) {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen++] = '-';
			else if (flags & FPLUS)
			    buf[blen++] = '+';
			else if (flags & FSPACE)
			    blen++;
			memcpy(&buf[blen], expr, strlen(expr));
		    }
		    else {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen + need - strlen(expr) - 1] = '-';
			else if (flags & FPLUS)
			    buf[blen + need - strlen(expr) - 1] = '+';
			else if ((flags & FSPACE) && need > width)
			    blen++;
			memcpy(&buf[blen + need - strlen(expr)], expr,
			       strlen(expr));
		    }
		    blen += strlen(&buf[blen]);
		    break;
		}

		fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
		need = 0;
		if (*p != 'e' && *p != 'E') {
		    i = INT_MIN;
		    frexp(fval, &i);
		    if (i > 0)
			need = BIT_DIGITS(i);
		}
		need += (flags&FPREC) ? prec : 6;
		if ((flags&FWIDTH) && need < width)
		    need = width;
		need += 20;

		CHECK(need);
		snprintf(&buf[blen], need, fbuf, fval);
		blen += strlen(&buf[blen]);
	    }
	    break;
	}
	flags = FNONE;
    }

  sprint_exit:
    /* XXX - We cannot validate the number of arguments if (digit)$ style used.
     */
    if (posarg >= 0 && nextarg < argc) {
	const char *mesg = "too many arguments for format string";
	if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg);
	if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
    }
    rb_str_resize(result, blen);

    if (tainted) OBJ_TAINT(result);
    return result;
}
示例#3
0
文件: sprintf.c 项目: nhinze/rhodes
VALUE
rb_str_format(int argc, const VALUE *argv, VALUE fmt)
{
    enum {default_float_precision = 6};
    rb_encoding *enc;
    const char *p, *end;
    char *buf;
    long blen, bsiz;
    VALUE result;

    long scanned = 0;
    int coderange = ENC_CODERANGE_7BIT;
    int width, prec, flags = FNONE;
    int nextarg = 1;
    int posarg = 0;
    int tainted = 0;
    VALUE nextvalue;
    VALUE tmp;
    VALUE str;
    volatile VALUE hash = Qundef;

#define CHECK_FOR_WIDTH(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "width given twice");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "width after precision"); \
    }
#define CHECK_FOR_FLAGS(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "flag after width");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "flag after precision"); \
    }

    ++argc;
    --argv;
    if (OBJ_TAINTED(fmt)) tainted = 1;
    StringValue(fmt);
    enc = rb_enc_get(fmt);
    fmt = rb_str_new4(fmt);
    p = RSTRING_PTR(fmt);
    end = p + RSTRING_LEN(fmt);
    blen = 0;
    bsiz = 120;
    result = rb_str_buf_new(bsiz);
    rb_enc_copy(result, fmt);
    buf = RSTRING_PTR(result);
    memset(buf, 0, bsiz);
    ENC_CODERANGE_SET(result, coderange);

    for (; p < end; p++) {
	const char *t;
	int n;
	VALUE sym = Qnil;

	for (t = p; t < end && *t != '%'; t++) ;
	PUSH(p, t - p);
	if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
	    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &coderange);
	    ENC_CODERANGE_SET(result, coderange);
	}
	if (t >= end) {
	    /* end of fmt string */
	    goto sprint_exit;
	}
	p = t + 1;		/* skip `%' */

	width = prec = -1;
	nextvalue = Qundef;
      retry:
	switch (*p) {
	  default:
	    if (rb_enc_isprint(*p, enc))
		rb_raise(rb_eArgError, "malformed format string - %%%c", *p);
	    else
		rb_raise(rb_eArgError, "malformed format string");
	    break;

	  case ' ':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSPACE;
	    p++;
	    goto retry;

	  case '#':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSHARP;
	    p++;
	    goto retry;

	  case '+':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FPLUS;
	    p++;
	    goto retry;

	  case '-':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FMINUS;
	    p++;
	    goto retry;

	  case '0':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FZERO;
	    p++;
	    goto retry;

	  case '1': case '2': case '3': case '4':
	  case '5': case '6': case '7': case '8': case '9':
	    n = 0;
	    GETNUM(n, width);
	    if (*p == '$') {
		if (nextvalue != Qundef) {
		    rb_raise(rb_eArgError, "value given twice - %d$", n);
		}
		nextvalue = GETPOSARG(n);
		p++;
		goto retry;
	    }
	    CHECK_FOR_WIDTH(flags);
	    width = n;
	    flags |= FWIDTH;
	    goto retry;

	  case '<':
	  case '{':
	    {
		const char *start = p;
		char term = (*p == '<') ? '>' : '}';
		int len;

		for (; p < end && *p != term; ) {
		    p += rb_enc_mbclen(p, end, enc);
		}
		if (p >= end) {
		    rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
		}
#if SIZEOF_INT < SIZEOF_SIZE_T
		if ((size_t)(p - start) >= INT_MAX) {
		    const int message_limit = 20;
		    len = (int)(rb_enc_right_char_head(start, start + message_limit, p, enc) - start);
		    rb_enc_raise(enc, rb_eArgError,
				 "too long name (%"PRIdSIZE" bytes) - %.*s...%c",
				 (size_t)(p - start - 2), len, start, term);
		}
#endif
		len = (int)(p - start + 1); /* including parenthesis */
		if (sym != Qnil) {
		    rb_enc_raise(enc, rb_eArgError, "named%.*s after <%"PRIsVALUE">",
				 len, start, rb_sym2str(sym));
		}
		CHECKNAMEARG(start, len, enc);
		get_hash(&hash, argc, argv);
		sym = rb_check_symbol_cstr(start + 1,
					   len - 2 /* without parenthesis */,
					   enc);
		if (!NIL_P(sym)) nextvalue = rb_hash_lookup2(hash, sym, Qundef);
		if (nextvalue == Qundef) {
		    if (NIL_P(sym)) {
			sym = rb_sym_intern(start + 1,
					    len - 2 /* without parenthesis */,
					    enc);
		    }
		    nextvalue = rb_hash_default_value(hash, sym);
		    if (NIL_P(nextvalue)) {
			rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start);
		    }
		}
		if (term == '}') goto format_s;
		p++;
		goto retry;
	    }

	  case '*':
	    CHECK_FOR_WIDTH(flags);
	    flags |= FWIDTH;
	    GETASTER(width);
	    if (width < 0) {
		flags |= FMINUS;
		width = -width;
	    }
	    p++;
	    goto retry;

	  case '.':
	    if (flags & FPREC0) {
		rb_raise(rb_eArgError, "precision given twice");
	    }
	    flags |= FPREC|FPREC0;

	    prec = 0;
	    p++;
	    if (*p == '*') {
		GETASTER(prec);
		if (prec < 0) {	/* ignore negative precision */
		    flags &= ~FPREC;
		}
		p++;
		goto retry;
	    }

	    GETNUM(prec, precision);
	    goto retry;

	  case '\n':
	  case '\0':
	    p--;
	  case '%':
	    if (flags != FNONE) {
		rb_raise(rb_eArgError, "invalid format character - %%");
	    }
	    PUSH("%", 1);
	    break;

	  case 'c':
	    {
		VALUE val = GETARG();
		VALUE tmp;
		unsigned int c;
		int n;

		tmp = rb_check_string_type(val);
		if (!NIL_P(tmp)) {
		    if (rb_enc_strlen(RSTRING_PTR(tmp),RSTRING_END(tmp),enc) != 1) {
			rb_raise(rb_eArgError, "%%c requires a character");
		    }
		    c = rb_enc_codepoint_len(RSTRING_PTR(tmp), RSTRING_END(tmp), &n, enc);
		    RB_GC_GUARD(tmp);
		}
		else {
		    c = NUM2INT(val);
		    n = rb_enc_codelen(c, enc);
		}
		if (n <= 0) {
		    rb_raise(rb_eArgError, "invalid character");
		}
		if (!(flags & FWIDTH)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
		else if ((flags & FMINUS)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		    if (width > 1) FILL(' ', width-1);
		}
		else {
		    if (width > 1) FILL(' ', width-1);
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
	    }
	    break;

	  case 's':
	  case 'p':
	  format_s:
	    {
		VALUE arg = GETARG();
		long len, slen;

		if (*p == 'p') {
		    str = rb_inspect(arg);
		}
		else {
		    str = rb_obj_as_string(arg);
		}
		if (OBJ_TAINTED(str)) tainted = 1;
		len = RSTRING_LEN(str);
		rb_str_set_len(result, blen);
		if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
		    int cr = coderange;
		    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr);
		    ENC_CODERANGE_SET(result,
				      (cr == ENC_CODERANGE_UNKNOWN ?
				       ENC_CODERANGE_BROKEN : (coderange = cr)));
		}
		enc = rb_enc_check(result, str);
		if (flags&(FPREC|FWIDTH)) {
		    slen = rb_enc_strlen(RSTRING_PTR(str),RSTRING_END(str),enc);
		    if (slen < 0) {
			rb_raise(rb_eArgError, "invalid mbstring sequence");
		    }
		    if ((flags&FPREC) && (prec < slen)) {
			char *p = rb_enc_nth(RSTRING_PTR(str), RSTRING_END(str),
					     prec, enc);
			slen = prec;
			len = p - RSTRING_PTR(str);
		    }
		    /* need to adjust multi-byte string pos */
		    if ((flags&FWIDTH) && (width > slen)) {
			width -= (int)slen;
			if (!(flags&FMINUS)) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			CHECK(len);
			memcpy(&buf[blen], RSTRING_PTR(str), len);
			RB_GC_GUARD(str);
			blen += len;
			if (flags&FMINUS) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			rb_enc_associate(result, enc);
			break;
		    }
		}
		PUSH(RSTRING_PTR(str), len);
		RB_GC_GUARD(str);
		rb_enc_associate(result, enc);
	    }
	    break;

	  case 'd':
	  case 'i':
	  case 'o':
	  case 'x':
	  case 'X':
	  case 'b':
	  case 'B':
	  case 'u':
	    {
		volatile VALUE val = GETARG();
                int valsign;
		char nbuf[64], *s;
		const char *prefix = 0;
		int sign = 0, dots = 0;
		char sc = 0;
		long v = 0;
		int base, bignum = 0;
		int len;

		switch (*p) {
		  case 'd':
		  case 'i':
		  case 'u':
		    sign = 1; break;
		  case 'o':
		  case 'x':
		  case 'X':
		  case 'b':
		  case 'B':
		    if (flags&(FPLUS|FSPACE)) sign = 1;
		    break;
		}
		if (flags & FSHARP) {
		    switch (*p) {
		      case 'o':
			prefix = "0"; break;
		      case 'x':
			prefix = "0x"; break;
		      case 'X':
			prefix = "0X"; break;
		      case 'b':
			prefix = "0b"; break;
		      case 'B':
			prefix = "0B"; break;
		    }
		}

	      bin_retry:
		switch (TYPE(val)) {
		  case T_FLOAT:
		    if (FIXABLE(RFLOAT_VALUE(val))) {
			val = LONG2FIX((long)RFLOAT_VALUE(val));
			goto bin_retry;
		    }
		    val = rb_dbl2big(RFLOAT_VALUE(val));
		    if (FIXNUM_P(val)) goto bin_retry;
		    bignum = 1;
		    break;
		  case T_STRING:
		    val = rb_str_to_inum(val, 0, TRUE);
		    goto bin_retry;
		  case T_BIGNUM:
		    bignum = 1;
		    break;
		  case T_FIXNUM:
		    v = FIX2LONG(val);
		    break;
		  default:
		    val = rb_Integer(val);
		    goto bin_retry;
		}

		switch (*p) {
		  case 'o':
		    base = 8; break;
		  case 'x':
		  case 'X':
		    base = 16; break;
		  case 'b':
		  case 'B':
		    base = 2; break;
		  case 'u':
		  case 'd':
		  case 'i':
		  default:
		    base = 10; break;
		}

                if (base != 10) {
                    int numbits = ffs(base)-1;
                    size_t abs_nlz_bits;
                    size_t numdigits = rb_absint_numwords(val, numbits, &abs_nlz_bits);
                    long i;
                    if (INT_MAX-1 < numdigits) /* INT_MAX is used because rb_long2int is used later. */
                        rb_raise(rb_eArgError, "size too big");
                    if (sign) {
                        if (numdigits == 0)
                            numdigits = 1;
                        tmp = rb_str_new(NULL, numdigits);
                        valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
                                1, CHAR_BIT-numbits, INTEGER_PACK_BIG_ENDIAN);
                        for (i = 0; i < RSTRING_LEN(tmp); i++)
                            RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
                        s = RSTRING_PTR(tmp);
                        if (valsign < 0) {
                            sc = '-';
                            width--;
                        }
                        else if (flags & FPLUS) {
                            sc = '+';
                            width--;
                        }
                        else if (flags & FSPACE) {
                            sc = ' ';
                            width--;
                        }
                    }
                    else {
                        /* Following conditional "numdigits++" guarantees the
                         * most significant digit as
                         * - '1'(bin), '7'(oct) or 'f'(hex) for negative numbers
                         * - '0' for zero
                         * - not '0' for positive numbers.
                         *
                         * It also guarantees the most significant two
                         * digits will not be '11'(bin), '77'(oct), 'ff'(hex)
                         * or '00'.  */
                        if (numdigits == 0 ||
                                ((abs_nlz_bits != (size_t)(numbits-1) ||
                                  !rb_absint_singlebit_p(val)) &&
                                 (!bignum ? v < 0 : BIGNUM_NEGATIVE_P(val))))
                            numdigits++;
                        tmp = rb_str_new(NULL, numdigits);
                        valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
                                1, CHAR_BIT-numbits, INTEGER_PACK_2COMP | INTEGER_PACK_BIG_ENDIAN);
                        for (i = 0; i < RSTRING_LEN(tmp); i++)
                            RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
                        s = RSTRING_PTR(tmp);
                        dots = valsign < 0;
                    }
                    len = rb_long2int(RSTRING_END(tmp) - s);
                }
                else if (!bignum) {
                    valsign = 1;
                    if (v < 0) {
                        v = -v;
                        sc = '-';
                        width--;
                        valsign = -1;
                    }
                    else if (flags & FPLUS) {
                        sc = '+';
                        width--;
                    }
                    else if (flags & FSPACE) {
                        sc = ' ';
                        width--;
                    }
                    snprintf(nbuf, sizeof(nbuf), "%ld", v);
                    s = nbuf;
		    len = (int)strlen(s);
		}
		else {
                    tmp = rb_big2str(val, 10);
                    s = RSTRING_PTR(tmp);
                    valsign = 1;
                    if (s[0] == '-') {
                        s++;
                        sc = '-';
                        width--;
                        valsign = -1;
                    }
                    else if (flags & FPLUS) {
                        sc = '+';
                        width--;
                    }
                    else if (flags & FSPACE) {
                        sc = ' ';
                        width--;
                    }
		    len = rb_long2int(RSTRING_END(tmp) - s);
		}

		if (dots) {
		    prec -= 2;
		    width -= 2;
		}

		if (*p == 'X') {
		    char *pp = s;
		    int c;
		    while ((c = (int)(unsigned char)*pp) != 0) {
			*pp = rb_enc_toupper(c, enc);
			pp++;
		    }
		}
		if (prefix && !prefix[1]) { /* octal */
		    if (dots) {
			prefix = 0;
		    }
		    else if (len == 1 && *s == '0') {
			len = 0;
			if (flags & FPREC) prec--;
		    }
		    else if ((flags & FPREC) && (prec > len)) {
			prefix = 0;
		    }
		}
		else if (len == 1 && *s == '0') {
		    prefix = 0;
		}
		if (prefix) {
		    width -= (int)strlen(prefix);
		}
		if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
		    prec = width;
		    width = 0;
		}
		else {
		    if (prec < len) {
			if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
			prec = len;
		    }
		    width -= prec;
		}
		if (!(flags&FMINUS)) {
		    CHECK(width);
		    while (width-- > 0) {
			buf[blen++] = ' ';
		    }
		}
		if (sc) PUSH(&sc, 1);
		if (prefix) {
		    int plen = (int)strlen(prefix);
		    PUSH(prefix, plen);
		}
		CHECK(prec - len);
		if (dots) PUSH("..", 2);
		if (!sign && valsign < 0) {
		    char c = sign_bits(base, p);
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		else if ((flags & (FMINUS|FPREC)) != FMINUS) {
		    while (len < prec--) {
			buf[blen++] = '0';
		    }
		}
		PUSH(s, len);
		RB_GC_GUARD(tmp);
		CHECK(width);
		while (width-- > 0) {
		    buf[blen++] = ' ';
		}
	    }
	    break;

	  case 'f':
	    {
		VALUE val = GETARG(), num, den;
		int sign = (flags&FPLUS) ? 1 : 0, zero = 0;
		long len, done = 0;
		int prefix = 0;
		if (FIXNUM_P(val) || RB_TYPE_P(val, T_BIGNUM)) {
		    den = INT2FIX(1);
		    num = val;
		}
		else if (RB_TYPE_P(val, T_RATIONAL)) {
		    den = rb_rational_den(val);
		    num = rb_rational_num(val);
		}
		else {
		    nextvalue = val;
		    goto float_value;
		}
		if (!(flags&FPREC)) prec = default_float_precision;
		if (FIXNUM_P(num)) {
		    if ((SIGNED_VALUE)num < 0) {
			long n = -FIX2LONG(num);
			num = LONG2FIX(n);
			sign = -1;
		    }
		}
		else if (rb_num_negative_p(num)) {
		    sign = -1;
		    num = rb_funcallv(num, idUMinus, 0, 0);
		}
		if (den != INT2FIX(1) || prec > 1) {
		    const ID idDiv = rb_intern("div");
		    VALUE p10 = rb_int_positive_pow(10, prec);
		    VALUE den_2 = rb_funcall(den, idDiv, 1, INT2FIX(2));
		    num = rb_funcallv(num, '*', 1, &p10);
		    num = rb_funcallv(num, '+', 1, &den_2);
		    num = rb_funcallv(num, idDiv, 1, &den);
		}
		else if (prec >= 0) {
		    zero = prec;
		}
		val = rb_obj_as_string(num);
		len = RSTRING_LEN(val) + zero;
		if (prec >= len) len = prec + 1; /* integer part 0 */
		if (sign || (flags&FSPACE)) ++len;
		if (prec > 0) ++len; /* period */
		CHECK(len > width ? len : width);
		if (sign || (flags&FSPACE)) {
		    buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' ';
		    prefix++;
		    done++;
		}
		len = RSTRING_LEN(val) + zero;
		t = RSTRING_PTR(val);
		if (len > prec) {
		    memcpy(&buf[blen], t, len - prec);
		    blen += len - prec;
		    done += len - prec;
		}
		else {
		    buf[blen++] = '0';
		    done++;
		}
		if (prec > 0) {
		    buf[blen++] = '.';
		    done++;
		}
		if (zero) {
		    FILL('0', zero);
		    done += zero;
		}
		else if (prec > len) {
		    FILL('0', prec - len);
		    memcpy(&buf[blen], t, len);
		    blen += len;
		    done += prec;
		}
		else if (prec > 0) {
		    memcpy(&buf[blen], t + len - prec, prec);
		    blen += prec;
		    done += prec;
		}
		if ((flags & FWIDTH) && width > done) {
		    int fill = ' ';
		    long shifting = 0;
		    if (!(flags&FMINUS)) {
			shifting = done;
			if (flags&FZERO) {
			    shifting -= prefix;
			    fill = '0';
			}
			blen -= shifting;
			memmove(&buf[blen + width - done], &buf[blen], shifting);
		    }
		    FILL(fill, width - done);
		    blen += shifting;
		}
		RB_GC_GUARD(val);
		break;
	    }
	  case 'g':
	  case 'G':
	  case 'e':
	  case 'E':
	    /* TODO: rational support */
	  case 'a':
	  case 'A':
	  float_value:
	    {
		VALUE val = GETARG();
		double fval;
		int i, need;
		char fbuf[32];

		fval = RFLOAT_VALUE(rb_Float(val));
		if (isnan(fval) || isinf(fval)) {
		    const char *expr;

		    if (isnan(fval)) {
			expr = "NaN";
		    }
		    else {
			expr = "Inf";
		    }
		    need = (int)strlen(expr);
		    if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
			need++;
		    if ((flags & FWIDTH) && need < width)
			need = width;

		    CHECK(need + 1);
		    snprintf(&buf[blen], need + 1, "%*s", need, "");
		    if (flags & FMINUS) {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen++] = '-';
			else if (flags & FPLUS)
			    buf[blen++] = '+';
			else if (flags & FSPACE)
			    blen++;
			memcpy(&buf[blen], expr, strlen(expr));
		    }
		    else {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen + need - strlen(expr) - 1] = '-';
			else if (flags & FPLUS)
			    buf[blen + need - strlen(expr) - 1] = '+';
			else if ((flags & FSPACE) && need > width)
			    blen++;
			memcpy(&buf[blen + need - strlen(expr)], expr,
			       strlen(expr));
		    }
		    blen += strlen(&buf[blen]);
		    break;
		}

		fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
		need = 0;
		if (*p != 'e' && *p != 'E') {
		    i = INT_MIN;
		    frexp(fval, &i);
		    if (i > 0)
			need = BIT_DIGITS(i);
		}
		need += (flags&FPREC) ? prec : default_float_precision;
		if ((flags&FWIDTH) && need < width)
		    need = width;
		need += 20;

		CHECK(need);
		snprintf(&buf[blen], need, fbuf, fval);
		blen += strlen(&buf[blen]);
	    }
	    break;
	}
	flags = FNONE;
    }

  sprint_exit:
    RB_GC_GUARD(fmt);
    /* XXX - We cannot validate the number of arguments if (digit)$ style used.
     */
    if (posarg >= 0 && nextarg < argc) {
	const char *mesg = "too many arguments for format string";
	if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg);
	if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
    }
    rb_str_resize(result, blen);

    if (tainted) OBJ_TAINT(result);
    return result;
}
示例#4
0
文件: hdr.c 项目: 0xPr0xy/ImageMagick
static MagickBooleanType WriteHDRImage(const ImageInfo *image_info,Image *image)
{
  char
    header[MaxTextExtent];

  const char
    *property;

  MagickBooleanType
    status;

  register const PixelPacket
    *p;

  register ssize_t
    i,
    x;

  size_t
    length;

  ssize_t
    count,
    y;

  unsigned char
    pixel[4],
    *pixels;

  /*
    Open output image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
  if (status == MagickFalse)
    return(status);
  if (IsRGBColorspace(image->colorspace) == MagickFalse)
    (void) TransformImageColorspace(image,sRGBColorspace);
  /*
    Write header.
  */
  (void) ResetMagickMemory(header,' ',MaxTextExtent);
  length=CopyMagickString(header,"#?RGBE\n",MaxTextExtent);
  (void) WriteBlob(image,length,(unsigned char *) header);
  property=GetImageProperty(image,"comment");
  if ((property != (const char *) NULL) &&
      (strchr(property,'\n') == (char *) NULL))
    {
      count=FormatLocaleString(header,MaxTextExtent,"#%s\n",property);
      (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
    }
  property=GetImageProperty(image,"hdr:exposure");
  if (property != (const char *) NULL)
    {
      count=FormatLocaleString(header,MaxTextExtent,"EXPOSURE=%g\n",
        atof(property));
      (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
    }
  if (image->gamma != 0.0)
    {
      count=FormatLocaleString(header,MaxTextExtent,"GAMMA=%g\n",image->gamma);
      (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
    }
  count=FormatLocaleString(header,MaxTextExtent,
    "PRIMARIES=%g %g %g %g %g %g %g %g\n",
    image->chromaticity.red_primary.x,image->chromaticity.red_primary.y,
    image->chromaticity.green_primary.x,image->chromaticity.green_primary.y,
    image->chromaticity.blue_primary.x,image->chromaticity.blue_primary.y,
    image->chromaticity.white_point.x,image->chromaticity.white_point.y);
  (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
  length=CopyMagickString(header,"FORMAT=32-bit_rle_rgbe\n\n",MaxTextExtent);
  (void) WriteBlob(image,length,(unsigned char *) header);
  count=FormatLocaleString(header,MaxTextExtent,"-Y %.20g +X %.20g\n",
    (double) image->rows,(double) image->columns);
  (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
  /*
    Write HDR pixels.
  */
  pixels=(unsigned char *) AcquireQuantumMemory(image->columns,4*
    sizeof(*pixels));
  if (pixels == (unsigned char *) NULL)
    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
    if (p == (const PixelPacket *) NULL)
      break;
    if ((image->columns >= 8) && (image->columns <= 0x7ffff))
      {
        pixel[0]=2;
        pixel[1]=2;
        pixel[2]=(unsigned char) (image->columns >> 8);
        pixel[3]=(unsigned char) (image->columns & 0xff);
        count=WriteBlob(image,4*sizeof(*pixel),pixel);
        if (count != (ssize_t) (4*sizeof(*pixel)))
          break;
      }
    i=0;
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      double
        gamma;

      pixel[0]=0;
      pixel[1]=0;
      pixel[2]=0;
      pixel[3]=0;
      gamma=QuantumScale*GetPixelRed(p);
      if ((QuantumScale*GetPixelGreen(p)) > gamma)
        gamma=QuantumScale*GetPixelGreen(p);
      if ((QuantumScale*GetPixelBlue(p)) > gamma)
        gamma=QuantumScale*GetPixelBlue(p);
      if (gamma > MagickEpsilon)
        {
          int
            exponent;

          gamma=frexp(gamma,&exponent)*256.0/gamma;
          pixel[0]=(unsigned char) (gamma*QuantumScale*GetPixelRed(p));
          pixel[1]=(unsigned char) (gamma*QuantumScale*GetPixelGreen(p));
          pixel[2]=(unsigned char) (gamma*QuantumScale*GetPixelBlue(p));
          pixel[3]=(unsigned char) (exponent+128);
        }
      if ((image->columns >= 8) && (image->columns <= 0x7ffff))
        {
          pixels[x]=pixel[0];
          pixels[x+image->columns]=pixel[1];
          pixels[x+2*image->columns]=pixel[2];
          pixels[x+3*image->columns]=pixel[3];
        }
      else
        {
          pixels[i++]=pixel[0];
          pixels[i++]=pixel[1];
          pixels[i++]=pixel[2];
          pixels[i++]=pixel[3];
        }
      p++;
    }
    if ((image->columns >= 8) && (image->columns <= 0x7ffff))
      {
        for (i=0; i < 4; i++)
          length=HDRWriteRunlengthPixels(image,&pixels[i*image->columns]);
      }
    else
      {
        count=WriteBlob(image,4*image->columns*sizeof(*pixel),pixel);
        if (count != (ssize_t) (4*image->columns*sizeof(*pixel)))
          break;
      }
    status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
      image->rows);
    if (status == MagickFalse)
      break;
  }
示例#5
0
GLbitfield GLAPIENTRY _mesa_QueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16])
{
    GLfloat matrix[16];
    GLint tmp;
    GLenum currentMode = GL_FALSE;
    GLenum desiredMatrix = GL_FALSE;
    /* The bitfield returns 1 for each component that is invalid (i.e.
     * NaN or Inf).  In case of error, everything is invalid.
     */
    GLbitfield rv;
    register unsigned int i;
    unsigned int bit;

    /* This data structure defines the mapping between the current matrix
     * mode and the desired matrix identifier.
     */
    static struct {
        GLenum currentMode;
        GLenum desiredMatrix;
    } modes[] = {
        {GL_MODELVIEW, GL_MODELVIEW_MATRIX},
        {GL_PROJECTION, GL_PROJECTION_MATRIX},
        {GL_TEXTURE, GL_TEXTURE_MATRIX},
    };

    /* Call Mesa to get the current matrix in floating-point form.  First,
     * we have to figure out what the current matrix mode is.
     */
    _mesa_GetIntegerv(GL_MATRIX_MODE, &tmp);
    currentMode = (GLenum) tmp;

    /* The mode is either GL_FALSE, if for some reason we failed to query
     * the mode, or a given mode from the above table.  Search for the
     * returned mode to get the desired matrix; if we don't find it,
     * we can return immediately, as _mesa_GetInteger() will have
     * logged the necessary error already.
     */
    for (i = 0; i < sizeof(modes)/sizeof(modes[0]); i++) {
        if (modes[i].currentMode == currentMode) {
            desiredMatrix = modes[i].desiredMatrix;
            break;
        }
    }
    if (desiredMatrix == GL_FALSE) {
        /* Early error means all values are invalid. */
        return 0xffff;
    }

    /* Now pull the matrix itself. */
    _mesa_GetFloatv(desiredMatrix, matrix);

    rv = 0;
    for (i = 0, bit = 1; i < 16; i++, bit<<=1) {
        float normalizedFraction;
        int exp;

        switch (fpclassify(matrix[i])) {
            /* A "subnormal" or denormalized number is too small to be
             * represented in normal format; but despite that it's a
             * valid floating point number.  FP_ZERO and FP_NORMAL
             * are both valid as well.  We should be fine treating
             * these three cases as legitimate floating-point numbers.
             */
            case FP_SUBNORMAL:
            case FP_NORMAL:
            case FP_ZERO:
                normalizedFraction = (GLfloat)frexp(matrix[i], &exp);
                mantissa[i] = FLOAT_TO_FIXED(normalizedFraction);
                exponent[i] = (GLint) exp;
                break;

            /* If the entry is not-a-number or an infinity, then the
             * matrix component is invalid.  The invalid flag for
             * the component is already set; might as well set the
             * other return values to known values.  We'll set
             * distinct values so that a savvy end user could determine
             * whether the matrix component was a NaN or an infinity,
             * but this is more useful for debugging than anything else
             * since the standard doesn't specify any such magic
             * values to return.
             */
            case FP_NAN:
                mantissa[i] = INT_TO_FIXED(0);
                exponent[i] = (GLint) 0;
                rv |= bit;
                break;

            case FP_INFINITE:
                /* Return +/- 1 based on whether it's a positive or
                 * negative infinity.
                 */
                if (matrix[i] > 0) {
                    mantissa[i] = INT_TO_FIXED(1);
                }
                else {
                    mantissa[i] = -INT_TO_FIXED(1);
                }
                exponent[i] = (GLint) 0;
                rv |= bit;
                break;

            /* We should never get here; but here's a catching case
             * in case fpclassify() is returnings something unexpected.
             */
            default:
                mantissa[i] = INT_TO_FIXED(2);
                exponent[i] = (GLint) 0;
                rv |= bit;
                break;
        }

    } /* for each component */

    /* All done */
    return rv;
}
示例#6
0
long double
frexpl (long double x, int *expptr)
{
  return frexp (x, expptr);
}
示例#7
0
static int math_frexp (lua_State *L) {
  int e;
  lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
  lua_pushinteger(L, e);
  return 2;
}
示例#8
0
static void math_frexp (void) {
  int e;
  lua_pushnumber(frexp(luaL_check_number(1), &e));
  lua_pushnumber(e);
}
示例#9
0
real_T b_scalar_erf(real_T x)
{
  real_T y;
  real_T absx;
  real_T s;
  real_T S;
  real_T R;
  int32_T eint;

  /* ========================== COPYRIGHT NOTICE ============================ */
  /*  The algorithms for calculating ERF(X) and ERFC(X) are derived           */
  /*  from FDLIBM, which has the following notice:                            */
  /*                                                                          */
  /*  Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.       */
  /*                                                                          */
  /*  Developed at SunSoft, a Sun Microsystems, Inc. business.                */
  /*  Permission to use, copy, modify, and distribute this                    */
  /*  software is freely granted, provided that this notice                   */
  /*  is preserved.                                                           */
  /* =============================    END    ================================ */
  absx = muDoubleScalarAbs(x);
  if (muDoubleScalarIsNaN(x)) {
    y = x;
  } else if (muDoubleScalarIsInf(x)) {
    if (x < 0.0) {
      y = -1.0;
    } else {
      y = 1.0;
    }
  } else if (absx < 0.84375) {
    if (absx < 3.7252902984619141E-9) {
      if (absx < 2.8480945388892178E-306) {
        y = 0.125 * (8.0 * x + 1.0270333367641007 * x);
      } else {
        y = x + 0.12837916709551259 * x;
      }
    } else {
      s = x * x;
      y = x + x * ((0.12837916709551256 + s * (-0.3250421072470015 + s *
        (-0.02848174957559851 + s * (-0.0057702702964894416 + s *
        -2.3763016656650163E-5)))) / (1.0 + s * (0.39791722395915535 + s *
        (0.0650222499887673 + s * (0.0050813062818757656 + s *
        (0.00013249473800432164 + s * -3.9602282787753681E-6))))));
    }
  } else if (absx < 1.25) {
    S = -0.0023621185607526594 + (absx - 1.0) * (0.41485611868374833 + (absx -
      1.0) * (-0.37220787603570132 + (absx - 1.0) * (0.31834661990116175 + (absx
      - 1.0) * (-0.11089469428239668 + (absx - 1.0) * (0.035478304325618236 +
      (absx - 1.0) * -0.0021663755948687908)))));
    s = 1.0 + (absx - 1.0) * (0.10642088040084423 + (absx - 1.0) *
      (0.540397917702171 + (absx - 1.0) * (0.071828654414196266 + (absx - 1.0) *
                                (0.12617121980876164 + (absx - 1.0) *
      (0.013637083912029051 + (absx - 1.0) * 0.011984499846799107)))));
    if (x >= 0.0) {
      y = 0.84506291151046753 + S / s;
    } else {
      y = -0.84506291151046753 - S / s;
    }
  } else if (absx > 6.0) {
    if (x < 0.0) {
      y = -1.0;
    } else {
      y = 1.0;
    }
  } else {
    s = 1.0 / (absx * absx);
    if (absx < 2.8571434020996094) {
      R = -0.0098649440348471482 + s * (-0.69385857270718176 + s *
        (-10.558626225323291 + s * (-62.375332450326006 + s *
        (-162.39666946257347 + s * (-184.60509290671104 + s * (-81.2874355063066
        + s * -9.8143293441691455))))));
      S = 1.0 + s * (19.651271667439257 + s * (137.65775414351904 + s *
        (434.56587747522923 + s * (645.38727173326788 + s * (429.00814002756783
        + s * (108.63500554177944 + s * (6.5702497703192817 + s *
        -0.0604244152148581)))))));
    } else {
      R = -0.0098649429247001 + s * (-0.799283237680523 + s *
        (-17.757954917754752 + s * (-160.63638485582192 + s *
        (-637.56644336838963 + s * (-1025.0951316110772 + s * -483.5191916086514)))));
      S = 1.0 + s * (30.338060743482458 + s * (325.79251299657392 + s *
        (1536.729586084437 + s * (3199.8582195085955 + s * (2553.0504064331644 +
        s * (474.52854120695537 + s * -22.440952446585818))))));
    }

    if ((!muDoubleScalarIsInf(absx)) && (!muDoubleScalarIsNaN(absx))) {
      s = frexp(absx, &eint);
    } else {
      s = absx;
      eint = 0;
    }

    s = muDoubleScalarFloor(s * 2.097152E+6) / 2.097152E+6 * muDoubleScalarPower
      (2.0, eint);
    y = muDoubleScalarExp(-s * s - 0.5625) * muDoubleScalarExp((s - absx) * (s +
      absx) + R / S) / absx;
    if (x < 0.0) {
      y--;
    } else {
      y = 1.0 - y;
    }
  }

  return y;
}
示例#10
0
float
frexpf (float x, int *exp)
{
  return (float) frexp (x, exp);
}
示例#11
0
PExpVal TExp::EvalExpOp(
 const PExpEnv& ExpEnv, const bool& DbgP, TChA& DbgChA){
  PExpVal OutExpVal;
  TExpOp _ExpOp=TExpOp(int(ExpOp));
  switch (_ExpOp){
    case eoUPlus:
    case eoUMinus:
    case eoNot:{
      PExpVal ExpVal=ArgExpV[0]->EvalExp(ExpEnv, DbgP, DbgChA);
      TExpValType ExpValType=ExpVal->GetValType();
      if (ExpValType==evtFlt){
        TFlt Flt;
        switch (_ExpOp){
          case eoUPlus: Flt=ExpVal->GetFltVal(); break;
          case eoUMinus: Flt=-ExpVal->GetFltVal(); break;
          case eoNot: Flt=double(ExpVal->GetFltValAsInt()==0);
          default: Fail; Flt=0;
        }
        OutExpVal=TExpVal::New(Flt);
      } else {
        TExcept::Throw("Bad argument types.");
      }
      break;}
    case eoPlus:
    case eoMinus:
    case eoMul:
    case eoDiv:
    case eoIDiv:
    case eoMod:
    case eoAnd:
    case eoOr:{
      PExpVal LExpVal=ArgExpV[0]->EvalExp(ExpEnv, DbgP, DbgChA);
      PExpVal RExpVal=ArgExpV[1]->EvalExp(ExpEnv, DbgP, DbgChA);
      TExpValType LExpValType=LExpVal->GetValType();
      TExpValType RExpValType=RExpVal->GetValType();
      if ((LExpValType==evtFlt)&&(RExpValType==evtFlt)){
        // check left expression
        double LVal=LExpVal->GetFltVal();
        int LValExpon; frexp(LVal, &LValExpon);
        if (LValExpon>150){LExpVal=TExpVal::GetZeroExpVal();}
        // check right expression
        double RVal=LExpVal->GetFltVal();
        int RValExpon; frexp(RVal, &RValExpon);
        if (RValExpon>150){RExpVal=TExpVal::GetZeroExpVal();}
        // calculate
        TFlt Flt;
        switch (_ExpOp){
          case eoPlus: Flt=LExpVal->GetFltVal()+RExpVal->GetFltVal(); break;
          case eoMinus: Flt=LExpVal->GetFltVal()-RExpVal->GetFltVal(); break;
          case eoMul: Flt=LExpVal->GetFltVal()*RExpVal->GetFltVal(); break;
          case eoDiv:
            if (RExpVal->GetFltVal()==0){TExcept::Throw("Division by zero.");}
            else {Flt=LExpVal->GetFltVal()/RExpVal->GetFltVal();}
            break;
          case eoIDiv:
            if (RExpVal->GetFltValAsInt()==0){TExcept::Throw("Division by zero.");}
            else {Flt=LExpVal->GetFltValAsInt()/RExpVal->GetFltValAsInt();}
            break;
          case eoMod:
            if (RExpVal->GetFltValAsInt()==0){TExcept::Throw("Division by zero.");}
            else {Flt=LExpVal->GetFltValAsInt()%RExpVal->GetFltValAsInt();}
            break;
          case eoAnd:
            Flt=(LExpVal->GetFltValAsInt()!=0)&&(RExpVal->GetFltValAsInt()!=0); break;
          case eoOr:
            Flt=(LExpVal->GetFltValAsInt()!=0)||(RExpVal->GetFltValAsInt()!=0); break;
          default: Fail; Flt=0;
        }
        OutExpVal=TExpVal::New(Flt);
      } else
      if ((_ExpOp==eoPlus)&&(LExpValType==evtStr)&&(RExpValType==evtStr)){
        TStr Str=LExpVal->GetStrVal()+RExpVal->GetStrVal();
        OutExpVal=TExpVal::New(Str);
      } else {
        TExcept::Throw("Bad argument types.");
      }
      break;}
    case eoEq:
    case eoNEq:
    case eoLss:
    case eoGtr:
    case eoLEq:
    case eoGEq:{
      PExpVal LExpVal=ArgExpV[0]->EvalExp(ExpEnv, DbgP, DbgChA);
      PExpVal RExpVal=ArgExpV[1]->EvalExp(ExpEnv, DbgP, DbgChA);
      TExpValType LExpValType=LExpVal->GetValType();
      TExpValType RExpValType=RExpVal->GetValType();
      if ((LExpValType==evtFlt)&&(RExpValType==evtFlt)){
        TFlt Flt;
        switch (_ExpOp){
          case eoEq: Flt=double(LExpVal->GetFltVal()==RExpVal->GetFltVal()); break;
          case eoNEq: Flt=double(LExpVal->GetFltVal()!=RExpVal->GetFltVal()); break;
          case eoLss: Flt=double(LExpVal->GetFltVal()<RExpVal->GetFltVal()); break;
          case eoGtr: Flt=double(LExpVal->GetFltVal()>RExpVal->GetFltVal()); break;
          case eoLEq: Flt=double(LExpVal->GetFltVal()<=RExpVal->GetFltVal()); break;
          case eoGEq: Flt=double(LExpVal->GetFltVal()>=RExpVal->GetFltVal()); break;
          default: Fail; Flt=0;
        }
        OutExpVal=TExpVal::New(Flt);
      } else
      if ((LExpValType==evtStr)&&(RExpValType==evtStr)){
        TFlt Flt;
        switch (_ExpOp){
          case eoEq: Flt=double(LExpVal->GetStrVal()==RExpVal->GetStrVal()); break;
          case eoNEq: Flt=double(LExpVal->GetStrVal()!=RExpVal->GetStrVal()); break;
          case eoLss: Flt=double(LExpVal->GetStrVal()<RExpVal->GetStrVal()); break;
          case eoGtr: Flt=double(LExpVal->GetStrVal()>RExpVal->GetStrVal()); break;
          case eoLEq: Flt=double(LExpVal->GetStrVal()<=RExpVal->GetStrVal()); break;
          case eoGEq: Flt=double(LExpVal->GetStrVal()>=RExpVal->GetStrVal()); break;
          default: Fail; Flt=0;
        }
        OutExpVal=TExpVal::New(Flt);
      } else {
        TExcept::Throw("Bad argument types.");
      }
      break;}
    case eoIf:{
      PExpVal CondExpVal=ArgExpV[0]->EvalExp(ExpEnv, DbgP, DbgChA);
      TExpValType CondExpValType=CondExpVal->GetValType();
      if (CondExpValType==evtFlt){
        PExpVal ExpVal;
        if (CondExpVal->GetFltVal()!=0){
          ExpVal=ArgExpV[1]->EvalExp(ExpEnv, DbgP, DbgChA);
        } else {
          ExpVal=ArgExpV[2]->EvalExp(ExpEnv, DbgP, DbgChA);
        }
        OutExpVal=ExpVal;
      } else {
        TExcept::Throw("Bad argument types.");
      }
      break;}
    default: Fail; OutExpVal=NULL;
  }
  if (DbgP){
    DbgChA+="['"; DbgChA+=TExp::GetExpOpStr(_ExpOp);
    DbgChA+="'='"; DbgChA+=OutExpVal->GetStr(); DbgChA+="'] ";
  }
  return OutExpVal;
}
示例#12
0
/* creates a waveform in the frequency domain; the waveform might be generated
 * in the time-domain and transformed */
int create_fd_waveform(COMPLEX16FrequencySeries ** htilde_plus, COMPLEX16FrequencySeries ** htilde_cross, struct params p)
{
    clock_t timer_start = 0;
    double chirplen, deltaF;
    int chirplen_exp;

    /* length of the chirp in samples */
    chirplen = imr_time_bound(p.f_min, p.m1, p.m2, p.s1z, p.s2z) * p.srate;
    /* make chirplen next power of two */
    frexp(chirplen, &chirplen_exp);
    chirplen = ldexp(1.0, chirplen_exp);
    deltaF = p.srate / chirplen;
    if (p.verbose)
        fprintf(stderr, "using frequency resolution deltaF = %g Hz\n", deltaF);

    if (p.condition) {
        if (p.verbose) {
            fprintf(stderr, "generating waveform in frequency domain using XLALSimInspiralFD...\n");
            timer_start = clock();
        }
        XLALSimInspiralFD(htilde_plus, htilde_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, deltaF, p.f_min, 0.5 * p.srate, p.fRef, p.params, p.approx);
        if (p.verbose)
            fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
    } else if (p.domain == LAL_SIM_DOMAIN_FREQUENCY) {
        if (p.verbose) {
            fprintf(stderr, "generating waveform in frequency domain using XLALSimInspiralChooseFDWaveform...\n");
            timer_start = clock();
        }
        XLALSimInspiralChooseFDWaveform(htilde_plus, htilde_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, deltaF, p.f_min, 0.5 * p.srate, p.fRef, p.params, p.approx);
        if (p.verbose)
            fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
    } else {
        REAL8TimeSeries *h_plus = NULL;
        REAL8TimeSeries *h_cross = NULL;
        REAL8FFTPlan *plan;

        /* generate time domain waveform */
        if (p.verbose) {
            fprintf(stderr, "generating waveform in time domain using XLALSimInspiralChooseTDWaveform...\n");
            timer_start = clock();
        }
        XLALSimInspiralChooseTDWaveform(&h_plus, &h_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, 1.0 / p.srate, p.f_min, p.fRef, p.params, p.approx);
        if (p.verbose)
            fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);

        /* resize the waveforms to the required length */
        XLALResizeREAL8TimeSeries(h_plus, h_plus->data->length - (size_t) chirplen, (size_t) chirplen);
        XLALResizeREAL8TimeSeries(h_cross, h_cross->data->length - (size_t) chirplen, (size_t) chirplen);

        /* put the waveform in the frequency domain */
        /* (the units will correct themselves) */
        if (p.verbose) {
            fprintf(stderr, "transforming waveform to frequency domain...\n");
            timer_start = clock();
        }
        *htilde_plus = XLALCreateCOMPLEX16FrequencySeries("htilde_plus", &h_plus->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
        *htilde_cross = XLALCreateCOMPLEX16FrequencySeries("htilde_cross", &h_cross->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
        plan = XLALCreateForwardREAL8FFTPlan((size_t) chirplen, 0);
        XLALREAL8TimeFreqFFT(*htilde_cross, h_cross, plan);
        XLALREAL8TimeFreqFFT(*htilde_plus, h_plus, plan);
        if (p.verbose)
            fprintf(stderr, "transformation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);

        /* clean up */
        XLALDestroyREAL8FFTPlan(plan);
        XLALDestroyREAL8TimeSeries(h_cross);
        XLALDestroyREAL8TimeSeries(h_plus);
    }
    return 0;
}
void test_extra(T)
{
   T t = 1;
   t = abs(t);
   t = abs(t*t);

   t = fabs(t);
   t = fabs(t*t);

   t = sqrt(t);
   t = sqrt(t*t);

   t = floor(t);
   t = floor(t*t);

   t = ceil(t);
   t = ceil(t*t);

   t = trunc(t);
   t = trunc(t*t);

   t = round(t);
   t = round(t*t);

   t = exp(t);
   t = exp(t*t);

   t = log(t);
   t = log(t*t);

   t = log10(t);
   t = log10(t*t);

   t = cos(t);
   t = cos(t*t);

   t = sin(t);
   t = sin(t*t);

   t = tan(t);
   t = tan(t*t);

   t = asin(t);
   t = asin(t*t);

   t = atan(t);
   t = atan(t*t);

   t = acos(t);
   t = acos(t*t);

   t = cosh(t);
   t = cosh(t*t);

   t = sinh(t);
   t = sinh(t*t);

   t = tanh(t);
   t = tanh(t*t);

   double dval = 2;
   t = pow(t, t);
   t = pow(t, t*t);
   t = pow(t, dval);
   t = pow(t*t, t);
   t = pow(t*t, t*t);
   t = pow(t*t, dval);
   t = pow(dval, t);
   t = pow(dval, t*t);

   t = atan2(t, t);
   t = atan2(t, t*t);
   t = atan2(t, dval);
   t = atan2(t*t, t);
   t = atan2(t*t, t*t);
   t = atan2(t*t, dval);
   t = atan2(dval, t);
   t = atan2(dval, t*t);

   t = fmod(t, t);
   t = fmod(t, t*t);
   t = fmod(t, dval);
   t = fmod(t*t, t);
   t = fmod(t*t, t*t);
   t = fmod(t*t, dval);
   t = fmod(dval, t);
   t = fmod(dval, t*t);

   typedef typename T::backend_type backend_type;
   typedef typename backend_type::exponent_type exp_type;
   exp_type e = 0;
   int i = 0;

   t = ldexp(t, i);
   t = ldexp(t*t, i);
   t = ldexp(t, e);
   t = ldexp(t*t, e);

   t = frexp(t, &i);
   t = frexp(t*t, &i);
   t = frexp(t, &e);
   t = frexp(t*t, &e);

   t = scalbn(t, i);
   t = scalbn(t*t, i);
   t = scalbn(t, e);
   t = scalbn(t*t, e);

   t = logb(t);
   t = logb(t*t);
   e = ilogb(t);
   e = ilogb(t*t);
}
示例#14
0
/* Function Definitions */
static boolean_T b_eml_relop(real_T a, const creal_T b, boolean_T safe_eq)
{
  boolean_T p;
  real_T x;
  real_T b_a;
  real_T b_b;
  boolean_T guard1 = FALSE;
  boolean_T guard2 = FALSE;
  boolean_T guard3 = FALSE;
  int32_T exponent;
  int32_T b_exponent;
  int32_T c_exponent;
  if ((fabs(a) > 8.9884656743115785E+307) || (fabs(b.re) >
       8.9884656743115785E+307) || (fabs(b.im) > 8.9884656743115785E+307)) {
    x = fabs(a) / 2.0;
    b_a = fabs(b.re / 2.0);
    b_b = fabs(b.im / 2.0);
    if (b_a < b_b) {
      b_a /= b_b;
      b_b *= sqrt(b_a * b_a + 1.0);
    } else if (b_a > b_b) {
      b_b /= b_a;
      b_b = sqrt(b_b * b_b + 1.0) * b_a;
    } else if (rtIsNaN(b_b)) {
    } else {
      b_b = b_a * 1.4142135623730951;
    }
  } else {
    x = fabs(a);
    b_a = fabs(b.re);
    b_b = fabs(b.im);
    if (b_a < b_b) {
      b_a /= b_b;
      b_b *= sqrt(b_a * b_a + 1.0);
    } else if (b_a > b_b) {
      b_b /= b_a;
      b_b = sqrt(b_b * b_b + 1.0) * b_a;
    } else if (rtIsNaN(b_b)) {
    } else {
      b_b = b_a * 1.4142135623730951;
    }
  }

  guard1 = FALSE;
  guard2 = FALSE;
  guard3 = FALSE;
  if ((!safe_eq) && (x == b_b)) {
    guard3 = TRUE;
  } else {
    if (safe_eq) {
      b_a = fabs(b_b / 2.0);
      if ((!rtIsInf(b_a)) && (!rtIsNaN(b_a))) {
        if (b_a <= 2.2250738585072014E-308) {
          b_a = 4.94065645841247E-324;
        } else {
          frexp(b_a, &exponent);
          b_a = ldexp(1.0, exponent - 53);
        }
      } else {
        b_a = rtNaN;
      }

      if ((fabs(b_b - x) < b_a) || (rtIsInf(x) && rtIsInf(b_b) && ((x > 0.0) ==
            (b_b > 0.0)))) {
        p = TRUE;
      } else {
        p = FALSE;
      }

      if (p) {
        guard3 = TRUE;
      }
    }
  }

  if (guard3 == TRUE) {
    x = rt_atan2d_snf(0.0, a);
    b_b = rt_atan2d_snf(b.im, b.re);
    if ((!safe_eq) && (x == b_b)) {
      guard2 = TRUE;
    } else {
      if (safe_eq) {
        b_a = fabs(b_b / 2.0);
        if ((!rtIsInf(b_a)) && (!rtIsNaN(b_a))) {
          if (b_a <= 2.2250738585072014E-308) {
            b_a = 4.94065645841247E-324;
          } else {
            frexp(b_a, &b_exponent);
            b_a = ldexp(1.0, b_exponent - 53);
          }
        } else {
          b_a = rtNaN;
        }

        if ((fabs(b_b - x) < b_a) || (rtIsInf(x) && rtIsInf(b_b) && ((x > 0.0) ==
              (b_b > 0.0)))) {
          p = TRUE;
        } else {
          p = FALSE;
        }

        if (p) {
          guard2 = TRUE;
        }
      }
    }
  }

  if (guard2 == TRUE) {
    x = fabs(a);
    b_b = fabs(b.re);
    if ((!safe_eq) && (x == b_b)) {
      guard1 = TRUE;
    } else {
      if (safe_eq) {
        b_a = b_b / 2.0;
        if ((!rtIsInf(b_a)) && (!rtIsNaN(b_a))) {
          if (b_a <= 2.2250738585072014E-308) {
            b_a = 4.94065645841247E-324;
          } else {
            frexp(b_a, &c_exponent);
            b_a = ldexp(1.0, c_exponent - 53);
          }
        } else {
          b_a = rtNaN;
        }

        if ((fabs(b_b - x) < b_a) || (rtIsInf(x) && rtIsInf(b_b) && ((x > 0.0) ==
              (b_b > 0.0)))) {
          p = TRUE;
        } else {
          p = FALSE;
        }

        if (p) {
          guard1 = TRUE;
        }
      }
    }
  }

  if (guard1 == TRUE) {
    x = 0.0;
    b_b = 0.0;
  }

  return x < b_b;
}
示例#15
0
static Lisp_Object lisp_fix_sub(Lisp_Object a, int roundmode)
/*
 * This converts from a double to a Lisp integer, which will
 * quite often have to be a bignum.  No overflow is permitted - the
 * result can always be accurate.
 */
{
    int32_t a0, a1, a2, a3;
    int x, x1;
    CSLbool negative;
    double d = float_of_number(a);
    if (M2_31_1 < d && d < TWO_31)
    {   int32_t a = (int32_t)d;
/*
 * If my floating point value is in the range -(2^31+1) to +2^31 (exclusive)
 * then when C truncates it I will get an integer in the inclusive range
 * from -2^31 to 2^31-1, i.e. the whole range of C 32-bit integers.
 * If I then apply a rounding mode other than truncation I may just have
 * overflow, which I have to detect specially.
 */
        int32_t w;
        double f;
        switch (roundmode)
        {
    case FIX_TRUNCATE:
            break;          /* C casts truncate, so this is OK */
    case FIX_ROUND:
            f = d - (double)a;
            if (f > 0.5)
            {   if (a == 0x7fffffff) return make_two_word_bignum(1, 0);
                else a++;
            }
            else if (f < -0.5)
            {   if (a == ~0x7fffffff)
                    return make_two_word_bignum(-2, 0x7fffffff);
                else a--;
            }
   /* The rounding rule on the next lines show what I do in 1/2ulp cases */
            else if (f == 0.5) a = (a+1) & ~1;
            else if (f == -0.5)
            {   if (a == ~0x7fffffff)
                    return make_two_word_bignum(-2, 0x7fffffff);
                else a = a & ~1;
            }
            break;
    case FIX_FLOOR:
            f = d - (double)a;
            if (f < 0.0)
            {   if (a == ~0x7fffffff)
                    return make_two_word_bignum(-2, 0x7fffffff);
                else a--;
            }
            break;
    case FIX_CEILING:
            f = d - (double)a;
            if (f > 0.0)
            {   if (a == 0x7fffffff) return make_two_word_bignum(1, 0);
                else a++;
            }
            break;
        }
        w = a & fix_mask;
        if (w == 0 || w == fix_mask) return fixnum_of_int(a);
        else if (!signed_overflow(a)) return make_one_word_bignum(a);
        else if (a > 0) return make_two_word_bignum(0, a);
        else return make_two_word_bignum(-1, clear_top_bit(a));
    }
    if (d < 0.0) d = -d, negative = YES;
    else negative = NO;
    d = frexp(d, &x); /* 0.5 <= abs(d) < 1.0, x = the (binary) exponent */
    if (d == 1.0) d = 0.5, x++;
    d *= TWO_31;
    a1 = (int32_t)d;      /* 2^31 > d >= 2^30 */
    d -= (double)a1;
    a2 = (uint32_t)(d*TWO_31);  /* This conversion should be exact */
    if (negative)
    {   if (a2 == 0) a1 = -a1;
        else a2 = clear_top_bit(-a2), a1 = ~a1;
    }
    x -= 62;
    if (x < 0)              /* Need to shift right x places */
    {   x = -x;             /* The shift amount here can be 31 at most... */
        a3 = a2 << (32 - x);
        a2 = clear_top_bit((a2 >> x) | (a1 << (31 - x)));
#ifdef SIGNED_SHIFTS_ARE_LOGICAL
        if (a1 < 0) a1 = (a1 >> x) | (((int32_t)-1) << (31 - x));
        else a1 = a1 >> x;
示例#16
0
inline mpfr_class frexp(const __gmp_expr<T,U>& v, int* expon)
{
   return frexp(static_cast<mpfr_class>(v), expon);
}
double
attribute_hidden
frexpl (double x, int *exponent)
{
  return frexp (x, exponent);
}
    double estimate(const std::vector<int>& c, int& outerLoopIterationsCount, int& innerLoop1IterationsCount, int& innerLoop2IterationsCount, int& logEvaluationCount) const {

        outerLoopIterationsCount = 0;
        innerLoop1IterationsCount = 0;
        innerLoop2IterationsCount = 0;
        logEvaluationCount = 0;

        if (c[q+1] == m) return std::numeric_limits<double>::infinity();

        int kMin, kMax;

        for(kMin=0; c[kMin]==0; ++kMin);
        int kMinPrime = std::max(1, kMin);

        for(kMax=q+1; c[kMax]==0; --kMax);
        int kMaxPrime = std::min(q, kMax);

        double z = 0.;
        for (int k = kMaxPrime; k >= kMinPrime; --k) {
            z = 0.5*z + c[k];
        }
        z = ldexp(z, -kMinPrime);

        int cPrime = c[q+1];
        if (q >= 1) {
            cPrime += c[kMaxPrime];
        }

        double gPrevious = 0;

        double x;
        double a = z + c[0];
        int mPrime = m - c[0];
        {
            double b = z + ldexp(c[q+1], -q);
            if (b <= 1.5*a) {
                x = mPrime/(0.5*b+a);
            }
            else {
                x = (mPrime/b)*log1p(b/a);
                logEvaluationCount += 1;
            }
        }

        double deltaX = x;
        while(deltaX > x*relativeErrorLimit) {
            int kappaMinus1;
            frexp(x, &kappaMinus1);
            double xPrime = ldexp(x, -std::max(kMaxPrime+1, kappaMinus1+2));
            double xPrime2 = xPrime*xPrime;
            double h = xPrime - xPrime2/3 + (xPrime2*xPrime2)*(1./45. - xPrime2/472.5);
            for (int k = kappaMinus1; k >= kMaxPrime; --k) {
                double hPrime = 1. - h;
                h = (xPrime + h*hPrime)/(xPrime+hPrime);
                xPrime += xPrime;
                innerLoop1IterationsCount += 1;
            }
            double g = cPrime*h;
            for (int k = kMaxPrime-1; k >= kMinPrime; --k) {
                double hPrime = 1. - h;
                h = (xPrime + h*hPrime)/(xPrime+hPrime);
                xPrime += xPrime;
                g += c[k] * h;
                innerLoop2IterationsCount += 1;
            }
            g += x*a;
            if (gPrevious < g && g <= mPrime) {
                deltaX *= (g-mPrime)/(gPrevious-g);
            }
            else {
                deltaX = 0;
            }
            x += deltaX;
            gPrevious = g;
            outerLoopIterationsCount += 1;
        }
        return x*m;
    }
示例#19
0
long double frexpl (long double x, int *exp)
{
	return (long double) frexp( (double)x, exp );
}
示例#20
0
void MathFrexp(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
    ReturnValue->Val->FP = frexp(Param[0]->Val->FP, Param[1]->Val->Pointer);
}
示例#21
0
ULONG MathFunc(CHAR *name, ULONG numargs, RXSTRING args[],
                        CHAR *queuename, RXSTRING *retstr)
{
	double x, y, result;
	int i, fn_id = -1;

#ifdef ENABLE_CACHE
   if (RxMathFncCache.id >= 0)
      fn_id = cache_func(name, numargs);

   if (fn_id < 0)
   {
   	fn_id = resolve_func(name, numargs);
	   if (fn_id < 0)           
		   return INVALID_ROUTINE;
   }
#else
  	fn_id = resolve_func(name, numargs);
   if (fn_id < 0)           
	   return INVALID_ROUTINE;
#endif

	x = atof(args[0].strptr);
	if (numargs > 1L)
	{
		y = atof(args[1].strptr);
		i = atoi(args[1].strptr);
	}

	switch (fn_id)
	{
	case fn_acos:
		result = acos(x);
		break;
	case fn_asin: 
		result = asin(x);
		break;
	case fn_atan: 
		result = atan(x);
		break;
	case fn_atan2:
		result = atan2(x, y);
		break;
	case fn_ceil: 
		result = ceil(x);
		break;
	case fn_cos:  
		result = cos(x);
		break;
	case fn_cosh: 
		result = cosh(x);
		break;
	case fn_exp:  
		result = exp(x);
		break;
	case fn_fabs: 
		result = fabs(x);
		break;
	case fn_floor:
		result = floor(x);
		break;
	case fn_fmod: 
		result = fmod(x, y);
		break;
	case fn_frexp:
		result = frexp(x, &i);
		break;
	case fn_ldexp:
		result = ldexp(x, i);
		break;
	case fn_log:  
		result = log(x);
		break;
	case fn_log10:
		result = log10(x);
		break;
	case fn_modf: 
		result = modf(x, &y);
		break;
	case fn_pow:  
		result = pow(x, y);
		break;
	case fn_sin:  
		result = sin(x);
		break;
	case fn_sinh: 
		result = sinh(x);
		break;
	case fn_sqrt: 
		result = sqrt(x);
		break;
	case fn_tan: 
		result = tan(x);
		break;
	case fn_tanh:
		result = tanh(x);
		break;
#ifdef __IBMC__
	case fn_erf:
      result = erf( x );
		break;
	case fn_erfc:  
      result = erfc( x );
		break;
	case fn_gamma: 
      result = gamma( x );
		break;
#endif
	case fn_hypot: 
      result = hypot( x, y );
		break;
	case fn_j0:    
      result = j0( x );
		break;
	case fn_j1:    
      result = j1( x );
		break;
	case fn_jn:    
      result = jn( i, x );
		break;
	case fn_y0:    
      result = y0( x );
		break;
	case fn_y1:    
      result = y1( x );
		break;
	case fn_yn:    
      result = yn( i, x );
		break;
	case fn_pi:    
      result = 3.1415926575;
		break;
   default:
	   return INVALID_ROUTINE;
	}

	switch (fn_id)
	{
	case fn_frexp:
		sprintf(retstr->strptr, "%lf %i", result, i);
		break;
	case fn_modf: 
		sprintf(retstr->strptr, "%lf %lf", result, y);
		break;
	default:
		sprintf(retstr->strptr, "%lf", result);
		break;
	}

	retstr->strlength = strlen(retstr->strptr);
	return VALID_ROUTINE;
}
示例#22
0
文件: nvvertexec.c 项目: basecq/q2dos
/**
 * Execute the given vertex program
 */
void
_mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
{
   struct vertex_program_state *state = &ctx->VertexProgram;
   const struct vp_instruction *inst;

   ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */

   /* If the program is position invariant, multiply the input
    * position and the MVP matrix and stick it into the output pos slot
    */
   if (ctx->VertexProgram.Current->IsPositionInvariant) {
      TRANSFORM_POINT( ctx->VertexProgram.Outputs[0], 
                       ctx->_ModelProjectMatrix.m, 
                       ctx->VertexProgram.Inputs[0]);

      /* XXX: This could go elsewhere */
      ctx->VertexProgram.Current->OutputsWritten |= 0x1;
   }

   for (inst = program->Instructions; /*inst->Opcode != VP_OPCODE_END*/; inst++) {

      if (ctx->VertexProgram.CallbackEnabled &&
          ctx->VertexProgram.Callback) {
         ctx->VertexProgram.CurrentPosition = inst->StringPos;
         ctx->VertexProgram.Callback(program->Base.Target,
                                     ctx->VertexProgram.CallbackData);
      }

      switch (inst->Opcode) {
         case VP_OPCODE_MOV:
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_LIT:
            {
               const GLfloat epsilon = 1.0e-5F; /* XXX fix? */
               GLfloat t[4], lit[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               if (t[3] < -(128.0F - epsilon))
                   t[3] = - (128.0F - epsilon);
               else if (t[3] > 128.0F - epsilon)
                  t[3] = 128.0F - epsilon;
               if (t[0] < 0.0)
                  t[0] = 0.0;
               if (t[1] < 0.0)
                  t[1] = 0.0;
               lit[0] = 1.0;
               lit[1] = t[0];
               lit[2] = (t[0] > 0.0) ? (GLfloat) exp(t[3] * log(t[1])) : 0.0F;
               lit[3] = 1.0;
               store_vector4( &inst->DstReg, state, lit );
            }
            break;
         case VP_OPCODE_RCP:
            {
               GLfloat t[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               if (t[0] != 1.0F)
                  t[0] = 1.0F / t[0];  /* div by zero is infinity! */
               t[1] = t[2] = t[3] = t[0];
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_RSQ:
            {
               GLfloat t[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               t[0] = INV_SQRTF(FABSF(t[0]));
               t[1] = t[2] = t[3] = t[0];
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_EXP:
            {
               GLfloat t[4], q[4], floor_t0;
               fetch_vector1( &inst->SrcReg[0], state, t );
               floor_t0 = (float) floor(t[0]);
               if (floor_t0 > FLT_MAX_EXP) {
                  SET_POS_INFINITY(q[0]);
                  SET_POS_INFINITY(q[2]);
               }
               else if (floor_t0 < FLT_MIN_EXP) {
                  q[0] = 0.0F;
                  q[2] = 0.0F;
               }
               else {
#ifdef USE_IEEE
                  GLint ii = (GLint) floor_t0;
                  ii = (ii < 23) + 0x3f800000;
                  SET_FLOAT_BITS(q[0], ii);
                  q[0] = *((GLfloat *) &ii);
#else
                  q[0] = (GLfloat) pow(2.0, floor_t0);
#endif
                  q[2] = (GLfloat) (q[0] * LOG2(q[1]));
               }
               q[1] = t[0] - floor_t0;
               q[3] = 1.0F;
               store_vector4( &inst->DstReg, state, q );
            }
            break;
         case VP_OPCODE_LOG:
            {
               GLfloat t[4], q[4], abs_t0;
               fetch_vector1( &inst->SrcReg[0], state, t );
               abs_t0 = (GLfloat) fabs(t[0]);
               if (abs_t0 != 0.0F) {
                  /* Since we really can't handle infinite values on VMS
                   * like other OSes we'll use __MAXFLOAT to represent
                   * infinity.  This may need some tweaking.
                   */
#ifdef VMS
                  if (abs_t0 == __MAXFLOAT)
#else
                  if (IS_INF_OR_NAN(abs_t0))
#endif
                  {
                     SET_POS_INFINITY(q[0]);
                     q[1] = 1.0F;
                     SET_POS_INFINITY(q[2]);
                  }
                  else {
                     int exponent;
                     double mantissa = frexp(t[0], &exponent);
                     q[0] = (GLfloat) (exponent - 1);
                     q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */
                     q[2] = (GLfloat) (q[0] + LOG2(q[1]));
                  }
                  }
               else {
                  SET_NEG_INFINITY(q[0]);
                  q[1] = 1.0F;
                  SET_NEG_INFINITY(q[2]);
               }
               q[3] = 1.0;
               store_vector4( &inst->DstReg, state, q );
            }
            break;
         case VP_OPCODE_MUL:
            {
               GLfloat t[4], u[4], prod[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               prod[0] = t[0] * u[0];
               prod[1] = t[1] * u[1];
               prod[2] = t[2] * u[2];
               prod[3] = t[3] * u[3];
               store_vector4( &inst->DstReg, state, prod );
            }
            break;
         case VP_OPCODE_ADD:
            {
               GLfloat t[4], u[4], sum[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               sum[0] = t[0] + u[0];
               sum[1] = t[1] + u[1];
               sum[2] = t[2] + u[2];
               sum[3] = t[3] + u[3];
               store_vector4( &inst->DstReg, state, sum );
            }
            break;
         case VP_OPCODE_DP3:
            {
               GLfloat t[4], u[4], dot[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2];
               dot[1] = dot[2] = dot[3] = dot[0];
               store_vector4( &inst->DstReg, state, dot );
            }
            break;
         case VP_OPCODE_DP4:
            {
               GLfloat t[4], u[4], dot[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3];
               dot[1] = dot[2] = dot[3] = dot[0];
               store_vector4( &inst->DstReg, state, dot );
            }
            break;
         case VP_OPCODE_DST:
            {
               GLfloat t[4], u[4], dst[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               dst[0] = 1.0F;
               dst[1] = t[1] * u[1];
               dst[2] = t[2];
               dst[3] = u[3];
               store_vector4( &inst->DstReg, state, dst );
            }
            break;
         case VP_OPCODE_MIN:
            {
               GLfloat t[4], u[4], min[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               min[0] = (t[0] < u[0]) ? t[0] : u[0];
               min[1] = (t[1] < u[1]) ? t[1] : u[1];
               min[2] = (t[2] < u[2]) ? t[2] : u[2];
               min[3] = (t[3] < u[3]) ? t[3] : u[3];
               store_vector4( &inst->DstReg, state, min );
            }
            break;
         case VP_OPCODE_MAX:
            {
               GLfloat t[4], u[4], max[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               max[0] = (t[0] > u[0]) ? t[0] : u[0];
               max[1] = (t[1] > u[1]) ? t[1] : u[1];
               max[2] = (t[2] > u[2]) ? t[2] : u[2];
               max[3] = (t[3] > u[3]) ? t[3] : u[3];
               store_vector4( &inst->DstReg, state, max );
            }
            break;
         case VP_OPCODE_SLT:
            {
               GLfloat t[4], u[4], slt[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F;
               slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F;
               slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F;
               slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F;
               store_vector4( &inst->DstReg, state, slt );
            }
            break;
         case VP_OPCODE_SGE:
            {
               GLfloat t[4], u[4], sge[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F;
               sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F;
               sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F;
               sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F;
               store_vector4( &inst->DstReg, state, sge );
            }
            break;
         case VP_OPCODE_MAD:
            {
               GLfloat t[4], u[4], v[4], sum[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               fetch_vector4( &inst->SrcReg[2], state, v );
               sum[0] = t[0] * u[0] + v[0];
               sum[1] = t[1] * u[1] + v[1];
               sum[2] = t[2] * u[2] + v[2];
               sum[3] = t[3] * u[3] + v[3];
               store_vector4( &inst->DstReg, state, sum );
            }
            break;
         case VP_OPCODE_ARL:
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               state->AddressReg[0] = (GLint) floor(t[0]);
            }
            break;
         case VP_OPCODE_DPH:
            {
               GLfloat t[4], u[4], dot[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3];
               dot[1] = dot[2] = dot[3] = dot[0];
               store_vector4( &inst->DstReg, state, dot );
            }
            break;
         case VP_OPCODE_RCC:
            {
               GLfloat t[4], u;
               fetch_vector1( &inst->SrcReg[0], state, t );
               if (t[0] == 1.0F)
                  u = 1.0F;
               else
                  u = 1.0F / t[0];
               if (u > 0.0F) {
                  if (u > 1.884467e+019F) {
                     u = 1.884467e+019F;  /* IEEE 32-bit binary value 0x5F800000 */
                  }
                  else if (u < 5.42101e-020F) {
                     u = 5.42101e-020F;   /* IEEE 32-bit binary value 0x1F800000 */
                  }
               }
               else {
                  if (u < -1.884467e+019F) {
                     u = -1.884467e+019F; /* IEEE 32-bit binary value 0xDF800000 */
                  }
                  else if (u > -5.42101e-020F) {
                     u = -5.42101e-020F;  /* IEEE 32-bit binary value 0x9F800000 */
                  }
               }
               t[0] = t[1] = t[2] = t[3] = u;
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_SUB: /* GL_NV_vertex_program1_1 */
            {
               GLfloat t[4], u[4], sum[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               sum[0] = t[0] - u[0];
               sum[1] = t[1] - u[1];
               sum[2] = t[2] - u[2];
               sum[3] = t[3] - u[3];
               store_vector4( &inst->DstReg, state, sum );
            }
            break;
         case VP_OPCODE_ABS: /* GL_NV_vertex_program1_1 */
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               if (t[0] < 0.0)  t[0] = -t[0];
               if (t[1] < 0.0)  t[1] = -t[1];
               if (t[2] < 0.0)  t[2] = -t[2];
               if (t[3] < 0.0)  t[3] = -t[3];
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_FLR: /* GL_ARB_vertex_program */
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               t[0] = FLOORF(t[0]);
               t[1] = FLOORF(t[1]);
               t[2] = FLOORF(t[2]);
               t[3] = FLOORF(t[3]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_FRC: /* GL_ARB_vertex_program */
            {
               GLfloat t[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               t[0] = t[0] - FLOORF(t[0]);
               t[1] = t[1] - FLOORF(t[1]);
               t[2] = t[2] - FLOORF(t[2]);
               t[3] = t[3] - FLOORF(t[3]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_EX2: /* GL_ARB_vertex_program */
            {
               GLfloat t[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(2.0, t[0]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_LG2: /* GL_ARB_vertex_program */
            {
               GLfloat t[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               t[0] = t[1] = t[2] = t[3] = LOG2(t[0]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_POW: /* GL_ARB_vertex_program */
            {
               GLfloat t[4], u[4];
               fetch_vector1( &inst->SrcReg[0], state, t );
               fetch_vector1( &inst->SrcReg[1], state, u );
               t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(t[0], u[0]);
               store_vector4( &inst->DstReg, state, t );
            }
            break;
         case VP_OPCODE_XPD: /* GL_ARB_vertex_program */
            {
               GLfloat t[4], u[4], cross[4];
               fetch_vector4( &inst->SrcReg[0], state, t );
               fetch_vector4( &inst->SrcReg[1], state, u );
               cross[0] = t[1] * u[2] - t[2] * u[1];
               cross[1] = t[2] * u[0] - t[0] * u[2];
               cross[2] = t[0] * u[1] - t[1] * u[0];
               store_vector4( &inst->DstReg, state, cross );
            }
            break;
         case VP_OPCODE_SWZ: /* GL_ARB_vertex_program */
            {
               const struct vp_src_register *source = &inst->SrcReg[0];
               const GLfloat *src = get_register_pointer(source, state);
               GLfloat result[4];
               GLuint i;

               /* do extended swizzling here */
               for (i = 0; i < 3; i++) {
                  if (source->Swizzle[i] == SWIZZLE_ZERO)
                     result[i] = 0.0;
                  else if (source->Swizzle[i] == SWIZZLE_ONE)
                     result[i] = -1.0;
                  else
                     result[i] = -src[source->Swizzle[i]];
                  if (source->Negate)
                     result[i] = -result[i];
               }
               store_vector4( &inst->DstReg, state, result );
            }
            break;

         case VP_OPCODE_END:
            ctx->_CurrentProgram = 0;
            return;
         default:
            /* bad instruction opcode */
            _mesa_problem(ctx, "Bad VP Opcode in _mesa_exec_vertex_program");
            ctx->_CurrentProgram = 0;
            return;
      } /* switch */
   } /* for */

   ctx->_CurrentProgram = 0;
}
示例#23
0
mrb_value
mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)
{
    const char *p, *end;
    char *buf;
    mrb_int blen;
    mrb_int bsiz;
    mrb_int n;
    mrb_int width;
    mrb_int prec;
    int flags = FNONE;
    int nextarg = 1;
    int posarg = 0;
    mrb_value nextvalue;
    mrb_value tmp;
    mrb_value str;
    mrb_value hash = mrb_value::undef();

#define CHECK_FOR_WIDTH(f)                                                  \
    if ((f) & FWIDTH) {                                                       \
    mrb->mrb_raise(E_ARGUMENT_ERROR, "width given twice");         \
}                                                                         \
    if ((f) & FPREC0) {                                                       \
    mrb->mrb_raise(E_ARGUMENT_ERROR, "width after precision");     \
}
#define CHECK_FOR_FLAGS(f)                                                  \
    if ((f) & FWIDTH) {                                                       \
    mrb->mrb_raise(E_ARGUMENT_ERROR, "flag after width");          \
}                                                                         \
    if ((f) & FPREC0) {                                                       \
    mrb->mrb_raise(E_ARGUMENT_ERROR, "flag after precision");      \
}

    ++argc;
    --argv;
    fmt = mrb_str_to_str(mrb, fmt);
    p = RSTRING_PTR(fmt);
    end = p + RSTRING_LEN(fmt);
    blen = 0;
    bsiz = 120;
    RString *res_ptr= RString::create(mrb,bsiz);
    buf = res_ptr->m_ptr;
    memset(buf, 0, bsiz);

    for (; p < end; p++) {
        const char *t;
        mrb_sym id = 0;

        for (t = p; t < end && *t != '%'; t++) ;
        PUSH(p, t - p);
        if (t >= end)
            goto sprint_exit; /* end of fmt string */

        p = t + 1;    /* skip `%' */

        width = prec = -1;
        nextvalue = mrb_value::undef();

retry:
        switch (*p) {
        default:
            mrb->mrb_raisef(E_ARGUMENT_ERROR, "malformed format string - \\%%S", mrb_str_new(mrb, p, 1));
            break;

        case ' ':
            CHECK_FOR_FLAGS(flags);
            flags |= FSPACE;
            p++;
            goto retry;

        case '#':
            CHECK_FOR_FLAGS(flags);
            flags |= FSHARP;
            p++;
            goto retry;

        case '+':
            CHECK_FOR_FLAGS(flags);
            flags |= FPLUS;
            p++;
            goto retry;

        case '-':
            CHECK_FOR_FLAGS(flags);
            flags |= FMINUS;
            p++;
            goto retry;

        case '0':
            CHECK_FOR_FLAGS(flags);
            flags |= FZERO;
            p++;
            goto retry;

        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            n = 0;
            GETNUM(n, width);
            if (*p == '$') {
                if (!nextvalue.is_undef()) {
                    mrb->mrb_raisef(E_ARGUMENT_ERROR, "value given twice - %S$", mrb_fixnum_value(n));
                }
                nextvalue = GETPOSARG(n);
                p++;
                goto retry;
            }
            CHECK_FOR_WIDTH(flags);
            width = n;
            flags |= FWIDTH;
            goto retry;

        case '<':
        case '{': {
            const char *start = p;
            char term = (*p == '<') ? '>' : '}';
            mrb_value symname;

            for (; p < end && *p != term; )
                p++;
            if (id) {
                mrb->mrb_raisef(E_ARGUMENT_ERROR, "name%S after <%S>",
                                mrb_str_new(mrb, start, p - start + 1), mrb_sym2str(mrb, id));
            }
            symname = mrb_str_new(mrb, start + 1, p - start - 1);
            id = mrb_intern_str(mrb, symname);
            nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1));
            if (nextvalue.is_undef()) {
                mrb->mrb_raisef(E_KEY_ERROR, "key%S not found", mrb_str_new(mrb, start, p - start + 1));
            }
            if (term == '}') goto format_s;
            p++;
            goto retry;
        }

        case '*':
            CHECK_FOR_WIDTH(flags);
            flags |= FWIDTH;
            GETASTER(width);
            if (width < 0) {
                flags |= FMINUS;
                width = -width;
            }
            p++;
            goto retry;

        case '.':
            if (flags & FPREC0) {
                mrb->mrb_raise(E_ARGUMENT_ERROR, "precision given twice");
            }
            flags |= FPREC|FPREC0;

            prec = 0;
            p++;
            if (*p == '*') {
                GETASTER(prec);
                if (prec < 0) {  /* ignore negative precision */
                    flags &= ~FPREC;
                }
                p++;
                goto retry;
            }

            GETNUM(prec, precision);
            goto retry;

        case '\n':
        case '\0':
            p--;

        case '%':
            if (flags != FNONE) {
                mrb->mrb_raise(E_ARGUMENT_ERROR, "invalid format character - %");
            }
            PUSH("%", 1);
            break;

        case 'c': {
            mrb_value val = GETARG();
            mrb_value tmp;
            unsigned int c;

            tmp = mrb_check_string_type(mrb, val);
            if (!tmp.is_nil()) {
                if (RSTRING_LEN(tmp) != 1 ) {
                    mrb->mrb_raise(E_ARGUMENT_ERROR, "%c requires a character");
                }
                c = RSTRING_PTR(tmp)[0];
                n = 1;
            }
            else {
                c = mrb_fixnum(val);
                n = 1;
            }
            if (n <= 0) {
                mrb->mrb_raise(E_ARGUMENT_ERROR, "invalid character");
            }
            if (!(flags & FWIDTH)) {
                CHECK(n);
                buf[blen] = c;
                blen += n;
            }
            else if ((flags & FMINUS)) {
                CHECK(n);
                buf[blen] = c;
                blen += n;
                FILL(' ', width-1);
            }
            else {
                FILL(' ', width-1);
                CHECK(n);
                buf[blen] = c;
                blen += n;
            }
        }
        break;

        case 's':
        case 'p':
format_s:
            {
                mrb_value arg = GETARG();
                mrb_int len;
                mrb_int slen;

                if (*p == 'p')
                    arg = mrb_inspect(mrb, arg)->wrap();
                str = mrb_obj_as_string(mrb, arg)->wrap();
                len = RSTRING_LEN(str);
                res_ptr->len = blen;
                if (flags&(FPREC|FWIDTH)) {
                    slen = RSTRING_LEN(str);
                    if (slen < 0) {
                        mrb->mrb_raise(E_ARGUMENT_ERROR, "invalid mbstring sequence");
                    }
                    if ((flags&FPREC) && (prec < slen)) {
                        char *p = RSTRING_PTR(str) + prec;
                        slen = prec;
                        len = p - RSTRING_PTR(str);
                    }
                    /* need to adjust multi-byte string pos */
                    if ((flags&FWIDTH) && (width > slen)) {
                        width -= (int)slen;
                        if (!(flags&FMINUS)) {
                            CHECK(width);
                            while (width--) {
                                buf[blen++] = ' ';
                            }
                        }
                        CHECK(len);
                        memcpy(&buf[blen], RSTRING_PTR(str), len);
                        blen += len;
                        if (flags&FMINUS) {
                            CHECK(width);
                            while (width--) {
                                buf[blen++] = ' ';
                            }
                        }
                        break;
                    }
                }
                PUSH(RSTRING_PTR(str), len);
            }
            break;

        case 'd':
        case 'i':
        case 'o':
        case 'x':
        case 'X':
        case 'b':
        case 'B':
        case 'u': {
            mrb_value val = GETARG();
            char fbuf[32], nbuf[64], *s;
            const char *prefix = NULL;
            int sign = 0, dots = 0;
            char sc = 0;
            mrb_int v = 0, org_v = 0;
            int base;
            mrb_int len;

            switch (*p) {
            case 'd':
            case 'i':
            case 'u':
                sign = 1;
                break;
            case 'o':
            case 'x':
            case 'X':
            case 'b':
            case 'B':
                if (flags&(FPLUS|FSPACE)) sign = 1;
                break;
            default:
                break;
            }
            if (flags & FSHARP) {
                switch (*p) {
                case 'o':
                    prefix = "0";
                    break;
                case 'x':
                    prefix = "0x";
                    break;
                case 'X':
                    prefix = "0X";
                    break;
                case 'b':
                    prefix = "0b";
                    break;
                case 'B':
                    prefix = "0B";
                    break;
                default:
                    break;
                }
            }

bin_retry:
            switch (mrb_type(val)) {
            case MRB_TT_FLOAT:
                if (FIXABLE(mrb_float(val))) {
                    val = mrb_fixnum_value((mrb_int)mrb_float(val));
                    goto bin_retry;
                }
                v = mrb_flo_to_fixnum(mrb, val);
                break;
            case MRB_TT_STRING:
                v = val.ptr<RString>()->mrb_str_to_inum(0, true);
                break;
            case MRB_TT_FIXNUM:
                v = mrb_fixnum(val);
                break;
            default:
                val = mrb_Integer(mrb, val);
                goto bin_retry;
            }

            switch (*p) {
            case 'o':
                base = 8;
                break;
            case 'x':
            case 'X':
                base = 16;
                break;
            case 'b':
            case 'B':
                base = 2;
                break;
            case 'u':
            case 'd':
            case 'i':
            default:
                base = 10;
                break;
            }

            if (base == 2) {
                org_v = v;
                RString *val_ptr;
                if ( v < 0 && !sign ) {
                    val_ptr = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
                    dots = 1;
                }
                else {
                    val_ptr = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);
                }
                v = val_ptr->mrb_str_to_inum(10, false);
            }
            if (sign) {
                char c = *p;
                if (c == 'i') c = 'd'; /* %d and %i are identical */
                if (base == 2) c = 'd';
                if (v < 0) {
                    v = -v;
                    sc = '-';
                    width--;
                }
                else if (flags & FPLUS) {
                    sc = '+';
                    width--;
                }
                else if (flags & FSPACE) {
                    sc = ' ';
                    width--;
                }
                snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
                snprintf(nbuf, sizeof(nbuf), fbuf, v);
                s = nbuf;
            }
            else {
                char c = *p;
                if (c == 'X') c = 'x';
                if (base == 2) c = 'd';
                s = nbuf;
                if (v < 0) {
                    dots = 1;
                }
                snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
                snprintf(++s, sizeof(nbuf) - 1, fbuf, v);
                if (v < 0) {
                    char d;

                    s = remove_sign_bits(s, base);
                    switch (base) {
                    case 16:
                        d = 'f';
                        break;
                    case 8:
                        d = '7';
                        break;
                    case 2:
                        d = '1';
                        break;
                    default:
                        d = 0;
                        break;
                    }

                    if (d && *s != d) {
                        *--s = d;
                    }
                }
            }
            {
                size_t size;
                size = strlen(s);
                /* PARANOID: assert(size <= MRB_INT_MAX) */
                len = (mrb_int)size;
            }

            if (dots) {
                prec -= 2;
                width -= 2;
            }

            if (*p == 'X') {
                char *pp = s;
                int c;
                while ((c = (int)(unsigned char)*pp) != 0) {
                    *pp = toupper(c);
                    pp++;
                }
            }

            if (prefix && !prefix[1]) { /* octal */
                if (dots) {
                    prefix = NULL;
                }
                else if (len == 1 && *s == '0') {
                    len = 0;
                    if (flags & FPREC) prec--;
                }
                else if ((flags & FPREC) && (prec > len)) {
                    prefix = NULL;
                }
            }
            else if (len == 1 && *s == '0') {
                prefix = NULL;
            }

            if (prefix) {
                size_t size;
                size = strlen(prefix);
                /* PARANOID: assert(size <= MRB_INT_MAX).
                *  this check is absolutely paranoid. */
                width -= (mrb_int)size;
            }

            if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
                prec = width;
                width = 0;
            }
            else {
                if (prec < len) {
                    if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
                    prec = len;
                }
                width -= prec;
            }

            if (!(flags&FMINUS)) {
                CHECK(width);
                while (width-- > 0) {
                    buf[blen++] = ' ';
                }
            }

            if (sc) PUSH(&sc, 1);

            if (prefix) {
                int plen = (int)strlen(prefix);
                PUSH(prefix, plen);
            }
            CHECK(prec - len);
            if (dots) PUSH("..", 2);

            if (v < 0 || (base == 2 && org_v < 0)) {
                char c = sign_bits(base, p);
                while (len < prec--) {
                    buf[blen++] = c;
                }
            }
            else if ((flags & (FMINUS|FPREC)) != FMINUS) {
                char c = '0';
                while (len < prec--) {
                    buf[blen++] = c;
                }
            }

            PUSH(s, len);
            CHECK(width);
            while (width-- > 0) {
                buf[blen++] = ' ';
            }
        }
        break;

        case 'f':
        case 'g':
        case 'G':
        case 'e':
        case 'E':
        case 'a':
        case 'A': {
            mrb_value val = GETARG();
            double fval;
            int i, need = 6;
            char fbuf[32];

            fval = mrb_float(mrb_Float(mrb, val));
            if (isnan(fval) || isinf(fval)) {
                const char *expr;
                const int elen = 3;

                if (isnan(fval)) {
                    expr = "NaN";
                }
                else {
                    expr = "Inf";
                }
                need = elen;
                if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
                    need++;
                if ((flags & FWIDTH) && need < width)
                    need = width;

                CHECK(need + 1);
                snprintf(&buf[blen], need + 1, "%*s", need, "");
                if (flags & FMINUS) {
                    if (!isnan(fval) && fval < 0.0)
                        buf[blen++] = '-';
                    else if (flags & FPLUS)
                        buf[blen++] = '+';
                    else if (flags & FSPACE)
                        blen++;
                    memcpy(&buf[blen], expr, elen);
                }
                else {
                    if (!isnan(fval) && fval < 0.0)
                        buf[blen + need - elen - 1] = '-';
                    else if (flags & FPLUS)
                        buf[blen + need - elen - 1] = '+';
                    else if ((flags & FSPACE) && need > width)
                        blen++;
                    memcpy(&buf[blen + need - elen], expr, elen);
                }
                blen += strlen(&buf[blen]);
                break;
            }

            fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
            need = 0;
            if (*p != 'e' && *p != 'E') {
                i = INT_MIN;
                frexp(fval, &i);
                if (i > 0)
                    need = BIT_DIGITS(i);
            }
            need += (flags&FPREC) ? prec : 6;
            if ((flags&FWIDTH) && need < width)
                need = width;
            need += 20;

            CHECK(need);
            n = snprintf(&buf[blen], need, fbuf, fval);
            blen += n;
        }
        break;
        }
        flags = FNONE;
    }

sprint_exit:
#if 0
    /* XXX - We cannot validate the number of arguments if (digit)$ style used.
    */
    if (posarg >= 0 && nextarg < argc) {
        const char *mesg = "too many arguments for format string";
        if (mrb_test(ruby_debug)) mrb->mrb_raise(E_ARGUMENT_ERROR, mesg);
        if (mrb_test(ruby_verbose)) mrb_warn(mrb,"%s", mesg);
    }
#endif
    res_ptr->resize(blen);
    return res_ptr->wrap();
}
//
// Arguments    : const emxArray_real_T *Y
//                double no[32]
//                double xo[32]
// Return Type  : void
//
void hist(const emxArray_real_T *Y, double no[32], double xo[32])
{
  int k;
  int b_Y[1];
  emxArray_real_T c_Y;
  double maxy;
  double miny;
  double edges[33];
  int exponent;
  int d_Y[1];
  double nn[33];
  k = Y->size[0];
  if (k == 0) {
    for (k = 0; k < 32; k++) {
      xo[k] = 1.0 + (double)k;
      no[k] = 0.0;
    }
  } else {
    b_Y[0] = Y->size[0];
    c_Y = *Y;
    c_Y.size = (int *)&b_Y;
    c_Y.numDimensions = 1;
    MinAndMaxNoNonFinites(&c_Y, &miny, &maxy);
    if (miny == maxy) {
      miny = (miny - 16.0) - 0.5;
      maxy = (maxy + 16.0) - 0.5;
    }

    linspace(miny, maxy, edges);
    miny = (edges[1] - edges[0]) / 2.0;
    for (k = 0; k < 32; k++) {
      xo[k] = edges[k] + miny;
    }

    edges[0] = rtMinusInf;
    edges[32] = rtInf;
    for (k = 0; k < 31; k++) {
      miny = std::abs(edges[k + 1]);
      if ((!rtIsInf(miny)) && (!rtIsNaN(miny))) {
        if (miny <= 2.2250738585072014E-308) {
          miny = 4.94065645841247E-324;
        } else {
          frexp(miny, &exponent);
          miny = std::ldexp(1.0, exponent - 53);
        }
      } else {
        miny = rtNaN;
      }

      edges[k + 1] += miny;
    }

    d_Y[0] = Y->size[0];
    c_Y = *Y;
    c_Y.size = (int *)&d_Y;
    c_Y.numDimensions = 1;
    histc(&c_Y, edges, nn);
    memcpy(&no[0], &nn[0], sizeof(double) << 5);
    no[31] += nn[32];
  }
}
static void
print_constant (FILE *out, JCF *jcf, int index, int verbosity)
{
  int j, n;
  jlong num;
  const char *str;
  int kind = JPOOL_TAG (jcf, index);
  switch (kind)
    {
    case CONSTANT_Class:
      n = JPOOL_USHORT1 (jcf, index);
      if (verbosity > 0)
	{
	  if (verbosity > 1)
	    fprintf (out, "Class name: %d=", n);
	  else
	    fprintf (out, "Class ");
	}
      if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, n))
	fprintf (out, "<out of range>");
      else if (verbosity < 2 && JPOOL_TAG (jcf, n) == CONSTANT_Utf8)
	{
	  int len = JPOOL_UTF_LENGTH (jcf, n);
	  jcf_print_utf8_replace (out, JPOOL_UTF_DATA(jcf,n), len, '/', '.');
	}
      else
	print_constant_terse (out, jcf, n, CONSTANT_Utf8);
      break;
    case CONSTANT_Fieldref:
      str = "Field"; goto field_or_method;
    case CONSTANT_Methodref:
      str = "Method"; goto field_or_method;
    case CONSTANT_InterfaceMethodref:
      str = "InterfaceMethod"; goto field_or_method;
    field_or_method:
      {
	uint16 tclass = JPOOL_USHORT1 (jcf, index);
	uint16 name_and_type = JPOOL_USHORT2 (jcf, index);
	if (verbosity == 2)
	  fprintf (out, "%sref class: %d=", str, tclass);
	else if (verbosity > 0)
	    fprintf (out, "%s ", str);
	print_constant_terse (out, jcf, tclass, CONSTANT_Class);
	if (verbosity < 2)
	  fprintf (out, ".");
	else
	  fprintf (out, " name_and_type: %d=<", name_and_type);
	print_constant_terse (out, jcf, name_and_type, CONSTANT_NameAndType);
	if (verbosity == 2)
	  fputc ('>', out);
      }
      break;
    case CONSTANT_String:
      j = JPOOL_USHORT1 (jcf, index);
      if (verbosity > 0)
	{
	  if (verbosity > 1)
	    fprintf (out, "String %d=", j);
	  else
	    fprintf (out, "String ");
	}
      print_constant_terse (out, jcf, j, CONSTANT_Utf8);
      break;
    case CONSTANT_Integer:
      if (verbosity > 0)
	fprintf (out, "Integer ");
      num = JPOOL_INT (jcf, index);
      goto integer;
    case CONSTANT_Long:
      if (verbosity > 0)
	fprintf (out, "Long ");
      num = JPOOL_LONG (jcf, index);
      goto integer;
    integer:
      {
	char buffer[25];
	format_int (buffer, num, 10);
	fprintf (out, "%s", buffer);
	if (verbosity > 1)
	  {
	    format_uint (buffer, (uint64)num, 16);
	    fprintf (out, "=0x%s", buffer);
	  }
      }
      break;
    case CONSTANT_Float:
      {
	jfloat fnum = JPOOL_FLOAT (jcf, index);

	if (verbosity > 0)
	  fputs ("Float ", out);

	if (fnum.negative)
	  putc ('-', out);

	if (JFLOAT_FINITE (fnum))
	  {
	    int dummy;
	    int exponent = fnum.exponent - JFLOAT_EXP_BIAS;
	    double f;
	    uint32 mantissa = fnum.mantissa;
	    if (fnum.exponent == 0)
	      /* Denormal.  */
	      exponent++;
	    else
	      /* Normal; add the implicit bit.  */
	      mantissa |= ((uint32)1 << 23);
	    
	    f = frexp (mantissa, &dummy);
	    f = ldexp (f, exponent + 1);
	    fprintf (out, "%.10g", f);
	  }
	else
	  {
	    if (fnum.mantissa == 0)
	      fputs ("Inf", out);
	    else if (fnum.mantissa & JFLOAT_QNAN_MASK)
	      fprintf (out, "QNaN(%u)", (fnum.mantissa & ~JFLOAT_QNAN_MASK));
	    else
	      fprintf (out, "SNaN(%u)", (fnum.mantissa & ~JFLOAT_QNAN_MASK));
	  }

	if (verbosity > 1)
	  fprintf (out, ", bits = 0x%08lx", JPOOL_UINT (jcf, index));
	
	break;
      }
    case CONSTANT_Double:
      {
	jdouble dnum = JPOOL_DOUBLE (jcf, index);

	if (verbosity > 0)
	  fputs ("Double ", out);

	if (dnum.negative)
	  putc ('-', out);

	if (JDOUBLE_FINITE (dnum))
	  {
	    int dummy;
	    int exponent = dnum.exponent - JDOUBLE_EXP_BIAS;
	    double d;
	    uint64 mantissa = ((((uint64) dnum.mantissa0) << 32)
			       + dnum.mantissa1);
	    if (dnum.exponent == 0)
	      /* Denormal.  */
	      exponent++;
	    else
	      /* Normal; add the implicit bit.  */
	      mantissa |= ((uint64)1 << 52);

	    d = frexp (mantissa, &dummy);
	    d = ldexp (d, exponent + 1);
	    fprintf (out, "%.20g", d);
	  }
	else
	  {
	    uint64 mantissa = dnum.mantissa0 & ~JDOUBLE_QNAN_MASK;
	    mantissa = (mantissa << 32) + dnum.mantissa1;

	    if (dnum.mantissa0 == 0 && dnum.mantissa1 == 0)
	      fputs ("Inf", out);
	    else if (dnum.mantissa0 & JDOUBLE_QNAN_MASK)
	      fprintf (out, "QNaN(%llu)", (unsigned long long)mantissa);
	    else
	      fprintf (out, "SNaN(%llu)", (unsigned long long)mantissa);
	  }
	if (verbosity > 1)
	  {
	    int32 hi, lo;
	    hi = JPOOL_UINT (jcf, index);
	    lo = JPOOL_UINT (jcf, index + 1);
	    fprintf (out, ", bits = 0x%08lx%08lx", (long) hi, (long) lo);
	  }
	break;
      }
    case CONSTANT_NameAndType:
      {
	uint16 name = JPOOL_USHORT1 (jcf, index);
	uint16 sig = JPOOL_USHORT2 (jcf, index);
	if (verbosity > 0)
	  {
	    if (verbosity > 1)
	      fprintf (out, "NameAndType name: %d=", name);
	    else
	      fprintf (out, "NameAndType ");
	  }
	print_name (out, jcf, name);
	if (verbosity <= 1)
	  fputc (' ', out);
	else
	  fprintf (out, ", signature: %d=", sig);
	print_signature (out, jcf, sig, 0);
      }
      break;
    case CONSTANT_Utf8:
      {
	const unsigned char *str = JPOOL_UTF_DATA (jcf, index);
	int length = JPOOL_UTF_LENGTH (jcf, index);
	if (verbosity > 0)
	  { /* Print as 8-bit bytes. */
	    fputs ("Utf8: \"", out);
	    while (--length >= 0)
	      jcf_print_char (out, *str++);
	  }
	else
	  { /* Print as Unicode. */
	    fputc ('\"', out);
	    jcf_print_utf8 (out, str, length);
	  }
	fputc ('\"', out);
      }
      break;
    default:
      fprintf (out, "(Unknown constant type %d)", kind);
    }
}
示例#26
0
文件: jv.c 项目: gertingold/scipy
static double jvs(double n, double x)
{
    double t, u, y, z, k;
    int ex;

    z = -x * x / 4.0;
    u = 1.0;
    y = u;
    k = 1.0;
    t = 1.0;

    while (t > MACHEP) {
	u *= z / (k * (n + k));
	y += u;
	k += 1.0;
	if (y != 0)
	    t = fabs(u / y);
    }
#if CEPHES_DEBUG
    printf("power series=%.5e ", y);
#endif
    t = frexp(0.5 * x, &ex);
    ex = ex * n;
    if ((ex > -1023)
	&& (ex < 1023)
	&& (n > 0.0)
	&& (n < (MAXGAM - 1.0))) {
	t = pow(0.5 * x, n) / gamma(n + 1.0);
#if CEPHES_DEBUG
	printf("pow(.5*x, %.4e)/gamma(n+1)=%.5e\n", n, t);
#endif
	y *= t;
    }
    else {
#if CEPHES_DEBUG
	z = n * log(0.5 * x);
	k = lgam(n + 1.0);
	t = z - k;
	printf("log pow=%.5e, lgam(%.4e)=%.5e\n", z, n + 1.0, k);
#else
	t = n * log(0.5 * x) - lgam(n + 1.0);
#endif
	if (y < 0) {
	    sgngam = -sgngam;
	    y = -y;
	}
	t += log(y);
#if CEPHES_DEBUG
	printf("log y=%.5e\n", log(y));
#endif
	if (t < -MAXLOG) {
	    return (0.0);
	}
	if (t > MAXLOG) {
	    mtherr("Jv", OVERFLOW);
	    return (NPY_INFINITY);
	}
	y = sgngam * exp(t);
    }
    return (y);
}
示例#27
0
文件: s_fma.c 项目: SylvestreG/bitrig
double
fma(double x, double y, double z)
{
	static const double split = 0x1p27 + 1.0;
	double xs, ys, zs;
	double c, cc, hx, hy, p, q, tx, ty;
	double r, rr, s;
	int oround;
	int ex, ey, ez;
	int spread;

	/*
	 * Handle special cases. The order of operations and the particular
	 * return values here are crucial in handling special cases involving
	 * infinities, NaNs, overflows, and signed zeroes correctly.
	 */
	if (x == 0.0 || y == 0.0)
		return (x * y + z);
	if (z == 0.0)
		return (x * y);
	if (!isfinite(x) || !isfinite(y))
		return (x * y + z);
	if (!isfinite(z))
		return (z);

	xs = frexp(x, &ex);
	ys = frexp(y, &ey);
	zs = frexp(z, &ez);
	oround = fegetround();
	spread = ex + ey - ez;

	/*
	 * If x * y and z are many orders of magnitude apart, the scaling
	 * will overflow, so we handle these cases specially.  Rounding
	 * modes other than FE_TONEAREST are painful.
	 */
	if (spread > DBL_MANT_DIG * 2) {
		fenv_t env;
		feraiseexcept(FE_INEXACT);
		switch(oround) {
		case FE_TONEAREST:
			return (x * y);
		case FE_TOWARDZERO:
			if ((x > 0.0) ^ (y < 0.0) ^ (z < 0.0))
				return (x * y);
			feholdexcept(&env);
			r = x * y;
			if (!fetestexcept(FE_INEXACT))
				r = nextafter(r, 0);
			feupdateenv(&env);
			return (r);
		case FE_DOWNWARD:
			if (z > 0.0)
				return (x * y);
			feholdexcept(&env);
			r = x * y;
			if (!fetestexcept(FE_INEXACT))
				r = nextafter(r, -INFINITY);
			feupdateenv(&env);
			return (r);
		default:	/* FE_UPWARD */
			if (z < 0.0)
				return (x * y);
			feholdexcept(&env);
			r = x * y;
			if (!fetestexcept(FE_INEXACT))
				r = nextafter(r, INFINITY);
			feupdateenv(&env);
			return (r);
		}
	}
	if (spread < -DBL_MANT_DIG) {
		feraiseexcept(FE_INEXACT);
		if (!isnormal(z))
			feraiseexcept(FE_UNDERFLOW);
		switch (oround) {
		case FE_TONEAREST:
			return (z);
		case FE_TOWARDZERO:
			if ((x > 0.0) ^ (y < 0.0) ^ (z < 0.0))
				return (z);
			else
				return (nextafter(z, 0));
		case FE_DOWNWARD:
			if ((x > 0.0) ^ (y < 0.0))
				return (z);
			else
				return (nextafter(z, -INFINITY));
		default:	/* FE_UPWARD */
			if ((x > 0.0) ^ (y < 0.0))
				return (nextafter(z, INFINITY));
			else
				return (z);
		}
	}

	/*
	 * Use Dekker's algorithm to perform the multiplication and
	 * subsequent addition in twice the machine precision.
	 * Arrange so that x * y = c + cc, and x * y + z = r + rr.
	 */
	fesetround(FE_TONEAREST);

	p = xs * split;
	hx = xs - p;
	hx += p;
	tx = xs - hx;

	p = ys * split;
	hy = ys - p;
	hy += p;
	ty = ys - hy;

	p = hx * hy;
	q = hx * ty + tx * hy;
	c = p + q;
	cc = p - c + q + tx * ty;

	zs = ldexp(zs, -spread);
	r = c + zs;
	s = r - c;
	rr = (c - (r - s)) + (zs - s) + cc;

	spread = ex + ey;
	if (spread + ilogb(r) > -1023) {
		fesetround(oround);
		r = r + rr;
	} else {
		/*
		 * The result is subnormal, so we round before scaling to
		 * avoid double rounding.
		 */
		p = ldexp(copysign(0x1p-1022, r), -spread);
		c = r + p;
		s = c - r;
		cc = (r - (c - s)) + (p - s) + rr;
		fesetround(oround);
		r = (c + cc) - p;
	}
	return (ldexp(r, spread));
}
GFC_REAL_8
set_exponent_r8 (GFC_REAL_8 s, GFC_INTEGER_4 i)
{
  int dummy_exp;
  return scalbn (frexp (s, &dummy_exp), i);
}
示例#29
0
void Babai (int kappa, F_mpz_mat_t B, double **mu, double **r, double *s, 
       double **appB, int *expo, double **appSP, 
       int a, int zeros, int kappamax, int n)
{
   int i, j, k, test, aa, exponent;
   signed long xx;
   double tmp, rtmp;
   
   aa = (a > zeros) ? a : zeros + 1;
  
   do
   {
      test = 0;
      
#ifdef DEBUG
      if (loops++ > LOOPS_BABAI) 
      {
	      printf("INFINITE LOOP?\n"); 
	      abort();
      }
#endif 
      
      /* ************************************** */
      /* Step2: compute the GSO for stage kappa */
      /* ************************************** */
      
      for (j = aa; j < kappa; j++)
	   {	  
	      if (appSP[kappa][j] != appSP[kappa][j]) // if appSP[kappa][j] == NAN
	      {
	         appSP[kappa][j] = d_vec_scalar_product(appB[kappa], appB[j], n);
	      }
	  	  
         if (j > zeros + 2)
	      {
	         tmp = mu[j][zeros+1] * r[kappa][zeros+1];
	         rtmp = appSP[kappa][j] - tmp;
	         for (k = zeros + 2; k < j - 1; k++)
		      {
		         tmp = mu[j][k] * r[kappa][k];
		         rtmp = rtmp - tmp;
		      }
	         tmp = mu[j][j-1] * r[kappa][j-1];
	         r[kappa][j] = rtmp - tmp;
         } else if (j == zeros+2)
	      {
	         tmp = mu[j][zeros+1] * r[kappa][zeros+1];
	         r[kappa][j] = appSP[kappa][j] - tmp;
	      } else r[kappa][j] = appSP[kappa][j];

	      mu[kappa][j] = r[kappa][j] / r[j][j];
      }
      
      /* **************************** */
      /* Step3--5: compute the X_j's  */
      /* **************************** */
      
      for (j = kappa - 1; j > zeros; j--)
	   {

	      /* test of the relaxed size-reduction condition */
	      tmp = fabs(mu[kappa][j]);
	      tmp = ldexp(tmp, expo[kappa] - expo[j]);
	  
	      if (tmp > halfplus) 
	      {
	         test = 1; 
	         exponent = expo[j] - expo[kappa];
	      
	         /* we consider separately the cases X = +-1 */     
	         if (tmp <= onedothalfplus)   
		      {		  
		         if (mu[kappa][j] >= 0)   /* in this case, X is 1 */
               {
		            for (k = zeros + 1; k < j; k++)
			         {
			            tmp = ldexp (mu[j][k], exponent);
			            mu[kappa][k] =  mu[kappa][k] - tmp; 
			         }
		      
		            F_mpz_mat_row_sub(B, kappa, B, kappa, B, j, 0, n);
		  
		         } else          /* otherwise X is -1 */ 
               {
                  for (k=zeros+1; k<j; k++)
			         {
			            tmp = ldexp (mu[j][k], exponent);
			            mu[kappa][k] = mu[kappa][k] + tmp;
			         }
		      
                  F_mpz_mat_row_add(B, kappa, B, kappa, B, j, 0, n); 
               }
		      } else   /* we must have |X| >= 2 */
		      {
		         tmp = ldexp (mu[kappa][j] , -exponent);

	            if ((tmp < (double) MAX_LONG) &&(tmp > (double) -MAX_LONG))  
		         {
		            tmp = rint (tmp); 
		      
		            for (k = zeros + 1; k < j; k++)
			         {
			            rtmp = tmp * mu[j][k];
			            rtmp = ldexp (rtmp, exponent);
			            mu[kappa][k] = mu[kappa][k] - rtmp;
			         }

		            xx = (long) tmp;
		      
                  if (xx > 0L)
                  { 
                     F_mpz_mat_row_submul_ui(B, kappa, B, j, 0, n, (ulong) xx);  
                  } else
                  {
                     F_mpz_mat_row_addmul_ui(B, kappa, B, j, 0, n, (ulong) -xx);  
                  } 
               } else
		         {
		            tmp = frexp(mu[kappa][j], &exponent); 
		            tmp = tmp * MAX_LONG;
		            xx = (long) tmp;
		            exponent += expo[kappa] - expo[j] - CPU_SIZE_1;

		            /* This case is extremely rare: never happened for me */
		            if (exponent <= 0) 
			         {
			            xx = xx << -exponent;
			            exponent = 0;
			  
			            if (xx > 0)
                     {
                        F_mpz_mat_row_submul_ui(B, kappa, B, j, 0, n, xx);  
                     } else
                     {
                        F_mpz_mat_row_addmul_ui(B, kappa, B, j, 0, n, -xx);  
                     }
              			    
			            for (k = zeros + 1; k < j; k++)
			            {
                        rtmp = ((double) xx) * mu[j][k];
			               rtmp = ldexp (rtmp, expo[j] - expo[kappa]);
			               mu[kappa][k] = mu[kappa][k] - rtmp;
			            }
			         } else
			         {
			            if (xx > 0)
                     {
                        F_mpz_mat_row_submul_2exp_ui(B, kappa, B, j, 0, n, (ulong) xx, exponent);  
                     } else
                     {
                        F_mpz_mat_row_addmul_2exp_ui(B, kappa, B, j, 0, n, (ulong) -xx, exponent);  
                     }
			            for (k = zeros + 1; k < j; k++)
			            {
			               rtmp = ((double) xx) * mu[j][k];
			               rtmp = ldexp (rtmp, exponent + expo[j] - expo[kappa]);
			               mu[kappa][k] = mu[kappa][k] - rtmp;
					      }
				      }	    
			      }
		      }
		   }
	   }

      if (test)   /* Anything happened? */
	   {
	      expo[kappa] = F_mpz_mat_set_line_d(appB[kappa], B, kappa, n);
	      aa = zeros + 1;
	      for (i = zeros + 1; i <= kappa; i++) 
	         appSP[kappa][i] = NAN;//0.0/0.0;
	      for (i = kappa + 1; i <= kappamax; i++) 
	         appSP[i][kappa] = NAN;//0.0/0.0;
	   }
   } while (test);

   if (appSP[kappa][kappa] != appSP[kappa][kappa]) 
   {
      appSP[kappa][kappa] = d_vec_norm(appB[kappa], n);
   }
   s[zeros + 1] = appSP[kappa][kappa];
  
   for (k = zeros + 1; k < kappa - 1; k++)
   {
      tmp = mu[kappa][k] * r[kappa][k];
      s[k+1] = s[k] - tmp;
   }
}
示例#30
0
文件: spectral.cpp 项目: Q55/windrose
/*
 * Fs -  Sampling frequency
 * Arguments    : double Fs
 *                emxArray_real_T *data
 *                emxArray_real_T *f
 *                emxArray_real_T *YY
 * Return Type  : void
 */
void spectral(double Fs, emxArray_real_T *data, emxArray_real_T *f,
              emxArray_real_T *YY)
{
  emxArray_boolean_T *b;
  int nxin;
  int k0;
  int nrowx;
  int nxout;
  int k;
  emxArray_real_T *b_data;
  int eint;
  double fdbl;
  double delta1;
  emxArray_creal_T *Y;
  double NFFT;
  emxArray_creal_T *x;
  emxInit_boolean_T(&b, 1);
  nxin = b->size[0];
  b->size[0] = data->size[0];
  emxEnsureCapacity((emxArray__common *)b, nxin, (int)sizeof(boolean_T));
  k0 = data->size[0];
  for (nxin = 0; nxin < k0; nxin++) {
    b->data[nxin] = rtIsNaN(data->data[nxin]);
  }

  nxin = data->size[0];
  nrowx = data->size[0];
  nxout = 0;
  for (k = 1; k <= b->size[0]; k++) {
    nxout += b->data[k - 1];
  }

  nxout = data->size[0] - nxout;
  k0 = -1;
  for (k = 1; k <= nxin; k++) {
    if ((k > b->size[0]) || (!b->data[k - 1])) {
      k0++;
      data->data[k0] = data->data[k - 1];
    }
  }

  emxFree_boolean_T(&b);
  if (nrowx != 1) {
    if (1 > nxout) {
      k0 = 0;
    } else {
      k0 = nxout;
    }

    emxInit_real_T(&b_data, 1);
    nxin = b_data->size[0];
    b_data->size[0] = k0;
    emxEnsureCapacity((emxArray__common *)b_data, nxin, (int)sizeof(double));
    for (nxin = 0; nxin < k0; nxin++) {
      b_data->data[nxin] = data->data[nxin];
    }

    nxin = data->size[0];
    data->size[0] = b_data->size[0];
    emxEnsureCapacity((emxArray__common *)data, nxin, (int)sizeof(double));
    k0 = b_data->size[0];
    for (nxin = 0; nxin < k0; nxin++) {
      data->data[nxin] = b_data->data[nxin];
    }

    emxFree_real_T(&b_data);
  } else {
    nxin = data->size[0];
    if (1 > nxout) {
      data->size[0] = 0;
    } else {
      data->size[0] = nxout;
    }

    emxEnsureCapacity((emxArray__common *)data, nxin, (int)sizeof(double));
  }

  fdbl = frexp(data->size[0], &eint);
  delta1 = eint;
  if (fdbl == 0.5) {
    delta1 = (double)eint - 1.0;
  }

  emxInit_creal_T(&Y, 1);
  NFFT = rt_powd_snf(2.0, delta1);

  /*  Next power of 2 from length of y */
  fft(data, NFFT, Y);
  nxout = data->size[0];
  nxin = Y->size[0];
  emxEnsureCapacity((emxArray__common *)Y, nxin, (int)sizeof(creal_T));
  k0 = Y->size[0];
  for (nxin = 0; nxin < k0; nxin++) {
    fdbl = Y->data[nxin].re;
    delta1 = Y->data[nxin].im;
    if (delta1 == 0.0) {
      Y->data[nxin].re = fdbl / (double)nxout;
      Y->data[nxin].im = 0.0;
    } else if (fdbl == 0.0) {
      Y->data[nxin].re = 0.0;
      Y->data[nxin].im = delta1 / (double)nxout;
    } else {
      Y->data[nxin].re = fdbl / (double)nxout;
      Y->data[nxin].im = delta1 / (double)nxout;
    }
  }

  fdbl = Fs / 2.0;
  nxin = f->size[0] * f->size[1];
  f->size[0] = 1;
  f->size[1] = (int)floor(NFFT / 2.0 + 1.0);
  emxEnsureCapacity((emxArray__common *)f, nxin, (int)sizeof(double));
  f->data[f->size[1] - 1] = 1.0;
  if (f->size[1] >= 2) {
    f->data[0] = 0.0;
    if (f->size[1] >= 3) {
      delta1 = 1.0 / ((double)f->size[1] - 1.0);
      nxin = f->size[1];
      for (k = 0; k <= nxin - 3; k++) {
        f->data[1 + k] = (1.0 + (double)k) * delta1;
      }
    }
  }

  nxin = f->size[0] * f->size[1];
  f->size[0] = 1;
  emxEnsureCapacity((emxArray__common *)f, nxin, (int)sizeof(double));
  nxout = f->size[0];
  k0 = f->size[1];
  k0 *= nxout;
  for (nxin = 0; nxin < k0; nxin++) {
    f->data[nxin] *= fdbl;
  }

  emxInit_creal_T(&x, 1);
  fdbl = NFFT / 2.0 + 1.0;
  k0 = (int)(NFFT / 2.0 + 1.0);
  nxin = x->size[0];
  x->size[0] = k0;
  emxEnsureCapacity((emxArray__common *)x, nxin, (int)sizeof(creal_T));
  for (nxin = 0; nxin < k0; nxin++) {
    x->data[nxin] = Y->data[nxin];
  }

  emxFree_creal_T(&Y);
  nxin = YY->size[0];
  YY->size[0] = (int)fdbl;
  emxEnsureCapacity((emxArray__common *)YY, nxin, (int)sizeof(double));
  for (k = 0; k + 1 <= (int)fdbl; k++) {
    YY->data[k] = rt_hypotd_snf(x->data[k].re, x->data[k].im);
  }

  emxFree_creal_T(&x);
  nxin = YY->size[0];
  emxEnsureCapacity((emxArray__common *)YY, nxin, (int)sizeof(double));
  k0 = YY->size[0];
  for (nxin = 0; nxin < k0; nxin++) {
    YY->data[nxin] *= 2.0;
  }

  /*  figure; */
  /*  plot(f,2*abs(Y(1:NFFT/2+1))); */
  /*  L = length(data);                                                 % Length of signal */
  /*  NFFT = 2^nextpow2(L); */
  /*  f = Fs/2*linspace(0,1,NFFT/2+1); */
  /*  figure(1) */
  /*  Y = fft(data,NFFT)/L; */
  /*  % Plot single-sided amplitude spectrum. */
  /*  plot(f,2*abs(Y(1:NFFT/2+1)))                                        % 船首向信号谱分析 */
  /*  set(gca,'xlim',[0.005 0.5],'ylimmode','auto');  */
  /*  title('艏向快速傅里叶变换'); */
  /*  xlabel('频率/Hz'); */
  /*  ylabel('功率'); */
  /*  box off */
}