int FPU_mul(FPU_REG const *b, u_char tagb, int deststnr, int control_w) { FPU_REG *a = &st(deststnr); FPU_REG *dest = a; u_char taga = FPU_gettagi(deststnr); u_char saved_sign = getsign(dest); u_char sign = (getsign(a) ^ getsign(b)); int tag; if (!(taga | tagb)) { tag = FPU_u_mul(a, b, dest, control_w, sign, exponent(a) + exponent(b)); if (tag < 0) { setsign(dest, saved_sign); return tag; } FPU_settagi(deststnr, tag); return tag; } if (taga == TAG_Special) taga = FPU_Special(a); if (tagb == TAG_Special) tagb = FPU_Special(b); if (((taga == TAG_Valid) && (tagb == TW_Denormal)) || ((taga == TW_Denormal) && (tagb == TAG_Valid)) || ((taga == TW_Denormal) && (tagb == TW_Denormal))) { FPU_REG x, y; if (denormal_operand() < 0) return FPU_Exception; FPU_to_exp16(a, &x); FPU_to_exp16(b, &y); tag = FPU_u_mul(&x, &y, dest, control_w, sign, exponent16(&x) + exponent16(&y)); if (tag < 0) { setsign(dest, saved_sign); return tag; } FPU_settagi(deststnr, tag); return tag; } else if ((taga <= TW_Denormal) && (tagb <= TW_Denormal)) { if (((tagb == TW_Denormal) || (taga == TW_Denormal)) && (denormal_operand() < 0)) return FPU_Exception; FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr); setsign(dest, sign); return TAG_Zero; } else if ((taga == TW_NaN) || (tagb == TW_NaN)) { return real_2op_NaN(b, tagb, deststnr, &st(0)); } else if (((taga == TW_Infinity) && (tagb == TAG_Zero)) || ((tagb == TW_Infinity) && (taga == TAG_Zero))) { return arith_invalid(deststnr); } else if (((taga == TW_Denormal) || (tagb == TW_Denormal)) && (denormal_operand() < 0)) { return FPU_Exception; } else if (taga == TW_Infinity) { FPU_copy_to_regi(a, TAG_Special, deststnr); setsign(dest, sign); return TAG_Special; } else if (tagb == TW_Infinity) { FPU_copy_to_regi(b, TAG_Special, deststnr); setsign(dest, sign); return TAG_Special; } #ifdef PARANOID else { EXCEPTION(EX_INTERNAL | 0x102); return FPU_Exception; } #endif return 0; }
//capturing only 8 significant digits right now. double check this. TOKEN number (TOKEN tok) { long num = 0; int c, charval; char integ[100]; char frac[100]; //null terminate these when done int decFound = 0, index = 0, decIndex = 0, integCount = 0, fracCount = 0, eFound = 0, i = 0; int tens = 0; //num * 10^0 initially int sigOffset = 0; //subtract from index to get number of significant digits int expo = 0; int startSig = 0; //once a significant figure is foundm, set to 1 int zerosAfterDec = 0; //counts the number of zeros after the decimal. use when there are only 0's before decimal int zerosBeforeDec = 0; //counts the number of zeros skipped before the decimal point. while ((c = peekchar()) != EOF && ((CHARCLASS[c] == NUMERIC) || c == '.' || c == 'e')){ while(((c = peekchar()) == '0' || c == '.') && !startSig){ //while(((c = peekchar()) == '0' || c == '.') && !startSig && CHARCLASS[c] == NUMERIC){ <- this does not work. dont try again c = getchar(); if(c == '.' && peekchar() == '.'){ //put back '.' and this number is done ungetc(c, stdin); tok->tokentype = NUMBERTOK; tok->datatype = INTEGER; tok->intval = num; return tok; //special condition for 0 followed by .. delimiter } if(c == '.'){ decFound = 1; decIndex = index; } else if(decFound && c == '0'){ //this is messing with frac[] array. something with decIndex i think... zerosAfterDec++; } else if(!decFound && c == '0'){ zerosBeforeDec++; } index++; } //printf("zerosAfterDec = %d, zerosBeforeDec = %d\n", zerosAfterDec, zerosBeforeDec); if(c == '.' && peek2char() == '.') break; startSig = 1; sigOffset = index; c = getchar(); if(c == 'e'){ expo = exponent(); eFound = 1; } else if(c == '.'){ decIndex = index; decFound = 1; } else if(CHARCLASS[c] == NUMERIC){ if(!decFound){ //adding integer part charval = (c - '0'); num = num * 10 + charval; integ[index - zerosBeforeDec] = c; integCount++; } else if(decFound && c != '.'){ frac[index - decIndex - zerosAfterDec - 1] = c; fracCount++; } } else //special case for 0 and trimming non significant digits ungetc(c, stdin); index++; } //if integer, check for overflow char maxint[10] = "2147483647"; int greater = 0; if(!decFound && integCount > 0){ if(integCount > 10) printf("ERROR: INTEGER OVERFLOW FOR FOLLOWING TOKEN\n"); if(integCount == 10){ int i = 0; while(integ[i] == maxint[i] && i < integCount) i++; if(i != integCount){ if(integ[i] > maxint[i]) printf("ERROR: INTEGER OVERFLOW FOR FOLLOWING TOKEN\n"); } } } //if decFound && integCount > 8. truncate and modify exponent char integ2[8]; if(decFound && integCount > 8){ fracCount = 0; //all 8 significant digits will be in integ[] expo += integCount - 8; integCount = 8; //recalculate num i = 0; num = 0; for(; i < 8; i++){ charval = integ[i] - '0'; num = num * 10 + charval; } } /* if(decFound && fracCount > 8){ integCount = 0; expo -= fracCount - 8; fracCount = 8; } */ tok->tokentype = NUMBERTOK; if(!decFound && !eFound){ tok->datatype = INTEGER; tok->intval = num; } else{ float mult = 0.1f; float fNum = num/1.0; int j = 0; for(; j < fracCount; j++){ fNum = fNum + (frac[j] - '0')*mult; mult /= 10; } if((expo - zerosAfterDec) > 38 || (expo - zerosAfterDec) < -38) printf("ERROR: FLOAT OVERFLOW FOR FOLLOWING TOKEN\n"); fNum = fNum * pow(10.0, expo/1.0) * pow(10.0, -zerosAfterDec/1.0); //adding in multiplication by factor of 10 tok->datatype = REAL; tok->realval = fNum; } return (tok); }
float getPoly(float x){ return 3*exponent(x,5)+2*exponent(x,4)-5*exponent(x,3)+exponent(x,2)+7*x-6; }
//(e^(-(x*x+y*y)/(2*sigma^2)))/(2*pi*sigma*sigma) void blur_gauss_2(u64 size,u64 radius,u8* src,u8* dst) { int x,y; int m,n; int width,height; double sigma; double temp; double r,g,b; //由公式:d = 6σ + 1,可以得到σ = r / 3. if(radius>9)radius=9; sigma=(double)radius; sigma/=3; //say("radius=%lld,sigma=%lf\n",radius,sigma); //first build the "gauss table" for(y=0;y<=radius;y++) { for(x=0;x<=radius;x++) { temp = (double)(-x*x-y*y); temp /= 2*sigma*sigma; gausstable[y][x] = exponent(temp); gausstable[y][x] /= 2*pi*sigma*sigma; //say("gausstable[%d][%d]=%lf\n",y,x,gausstable[y][x]); } } //开始 width=size&0xffff; height=(size>>16)&0xffff; for(y=radius;y<height-radius;y++) { for(x=radius;x<width-radius;x++) { //process this pixel r=g=b=0.0; //<0 for(n=-radius;n<0;n++) { //<0 for(m=-radius;m<0;m++) { // temp=gausstable[-n][-m]; //b b+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+0]; //g g+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+1]; //r r+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+2]; } //>0 for(m=0;m<radius;m++) { // temp=gausstable[-n][m]; //b b+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+0]; //g g+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+1]; //r r+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+2]; }//m }//n //>0 for(n=0;n<radius;n++) { //<0 for(m=-radius;m<0;m++) { // temp=gausstable[n][-m]; //b b+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+0]; //g g+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+1]; //r r+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+2]; } //>0 for(m=0;m<radius;m++) { // temp=gausstable[n][m]; //b b+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+0]; //g g+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+1]; //r r+=temp*(double)src[ ( (width*(y+n) + (x+m) )<<2)+2]; }//m }//n //put the result //say("(%d,%d):%lf,%lf,%lf\n",x,y,b,g,r); dst[((width*y+x)<<2)+0]=(int)b; dst[((width*y+x)<<2)+1]=(int)g; dst[((width*y+x)<<2)+2]=(int)r; /* //compiler bug? //can not use "n=-radius;n<radius;n++" for(n=-radius;n<radius;n++) { for(m=-radius;m<radius;m++) { say("(%d,%d)(%d,%d)\n",x,y,m,n); } } */ }//x }//y }
int __printf_render_float(struct __printf_io* io, const struct printf_info* pi, const void* const* arg) { int prec; /* precision from format; <0 for N/A */ char* dtoaresult; /* buffer allocated by dtoa */ char expchar; /* exponent character: [eEpP\0] */ char* cp; int expt; /* integer value of exponent */ int signflag; /* true if float is negative */ char* dtoaend; /* pointer to end of converted digits */ char sign; /* sign prefix (' ', '+', '-', or \0) */ int size; /* size of converted field or string */ int ndig; /* actual number of digits returned by dtoa */ int expsize; /* character count for expstr */ char expstr[MAXEXPDIG + 2]; /* buffer for exponent string: e+ZZZ */ int nseps; /* number of group separators with ' */ int nrepeats; /* number of repeats of the last group */ const char* grouping; /* locale specific numeric grouping rules */ int lead; /* sig figs before decimal or group sep */ long double ld; double d; int realsz; /* field size expanded by dprec, sign, etc */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */ char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */ int prsize; /* max size of printed field */ int ret; /* return value accumulator */ char* decimal_point; /* locale specific decimal point */ int n2; /* XXX: for PRINTANDPAD */ char thousands_sep; /* locale specific thousands separator */ char buf[BUF]; /* buffer with space for digits of uintmax_t */ const char* xdigs; int flag; prec = pi->prec; ox[1] = '\0'; sign = pi->showsign; flag = 0; ret = 0; thousands_sep = *(localeconv()->thousands_sep); grouping = NULL; if (pi->alt) { grouping = localeconv()->grouping; } decimal_point = localeconv()->decimal_point; dprec = -1; switch (pi->spec) { case 'a': case 'A': if (pi->spec == 'a') { ox[1] = 'x'; xdigs = __lowercase_hex; expchar = 'p'; } else { ox[1] = 'X'; xdigs = __uppercase_hex; expchar = 'P'; } if (prec >= 0) { prec++; } if (pi->is_long_double) { ld = *((long double*)arg[0]); dtoaresult = cp = __hldtoa(ld, xdigs, prec, &expt, &signflag, &dtoaend); } else { d = *((double*)arg[0]); dtoaresult = cp = __hdtoa(d, xdigs, prec, &expt, &signflag, &dtoaend); } if (prec < 0) { prec = dtoaend - cp; } if (expt == INT_MAX) { ox[1] = '\0'; } goto fp_common; case 'e': case 'E': expchar = pi->spec; if (prec < 0) { /* account for digit before decpt */ prec = DEFPREC + 1; } else { prec++; } break; case 'f': case 'F': expchar = '\0'; break; case 'g': case 'G': expchar = pi->spec - ('g' - 'e'); if (prec == 0) { prec = 1; } break; default: assert(pi->spec == 'f'); } if (prec < 0) { prec = DEFPREC; } if (pi->is_long_double) { ld = *((long double*)arg[0]); dtoaresult = cp = __ldtoa(&ld, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); } else { d = *((double*)arg[0]); dtoaresult = cp = dtoa(d, expchar ? 2 : 3, prec, &expt, &signflag, &dtoaend); if (expt == 9999) { expt = INT_MAX; } } fp_common: if (signflag) { sign = '-'; } if (expt == INT_MAX) { /* inf or nan */ if (*cp == 'N') { cp = (pi->spec >= 'a') ? "nan" : "NAN"; sign = '\0'; } else { cp = (pi->spec >= 'a') ? "inf" : "INF"; } size = 3; flag = 1; goto here; } ndig = dtoaend - cp; if (pi->spec == 'g' || pi->spec == 'G') { if (expt > -4 && expt <= prec) { /* Make %[gG] smell like %[fF] */ expchar = '\0'; if (pi->alt) { prec -= expt; } else { prec = ndig - expt; } if (prec < 0) { prec = 0; } } else { /* * Make %[gG] smell like %[eE], but * trim trailing zeroes if no # flag. */ if (!pi->alt) { prec = ndig; } } } if (expchar) { expsize = exponent(expstr, expt - 1, expchar); size = expsize + prec; if (prec > 1 || pi->alt) { ++size; } } else { /* space for digits before decimal point */ if (expt > 0) { size = expt; } else { /* "0" */ size = 1; } /* space for decimal pt and following digits */ if (prec || pi->alt) { size += prec + 1; } if (grouping && expt > 0) { /* space for thousands' grouping */ nseps = nrepeats = 0; lead = expt; while (*grouping != CHAR_MAX) { if (lead <= *grouping) { break; } lead -= *grouping; if (*(grouping + 1)) { nseps++; grouping++; } else { nrepeats++; } } size += nseps + nrepeats; } else { lead = expt; } } here: /* * All reasonable formats wind up here. At this point, `cp' * points to a string which (if not flags&LADJUST) should be * padded out to `width' places. If flags&ZEROPAD, it should * first be prefixed by any sign or other prefix; otherwise, * it should be blank padded before the prefix is emitted. * After any left-hand padding and prefixing, emit zeroes * required by a decimal [diouxX] precision, then print the * string proper, then emit zeroes required by any leftover * floating precision; finally, if LADJUST, pad with blanks. * * Compute actual size, so we know how much to pad. * size excludes decimal prec; realsz includes it. */ realsz = dprec > size ? dprec : size; if (sign) { realsz++; } if (ox[1]) { realsz += 2; } prsize = pi->width > realsz ? pi->width : realsz; /* right-adjusting blank padding */ if (pi->pad != '0' && pi->left == 0) { ret += __printf_pad(io, pi->width - realsz, 0); } /* prefix */ if (sign) { ret += __printf_puts(io, &sign, 1); } if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; ret += __printf_puts(io, ox, 2); } /* right-adjusting zero padding */ if (pi->pad == '0' && pi->left == 0) { ret += __printf_pad(io, pi->width - realsz, 1); } /* leading zeroes from decimal precision */ ret += __printf_pad(io, dprec - size, 1); if (flag) { ret += __printf_puts(io, cp, size); } else { /* glue together f_p fragments */ if (!expchar) { /* %[fF] or sufficiently short %[gG] */ if (expt <= 0) { ret += __printf_puts(io, "0", 1); if (prec || pi->alt) { ret += __printf_puts(io, decimal_point, 1); } ret += __printf_pad(io, -expt, 1); /* already handled initial 0's */ prec += expt; } else { PRINTANDPAD(cp, dtoaend, lead, 1); cp += lead; if (grouping) { while (nseps > 0 || nrepeats > 0) { if (nrepeats > 0) { nrepeats--; } else { grouping--; nseps--; } ret += __printf_puts(io, &thousands_sep, 1); PRINTANDPAD(cp, dtoaend, *grouping, 1); cp += *grouping; } if (cp > dtoaend) { cp = dtoaend; } } if (prec || pi->alt) { ret += __printf_puts(io, decimal_point, 1); } } PRINTANDPAD(cp, dtoaend, prec, 1); } else { /* %[eE] or sufficiently long %[gG] */ if (prec > 1 || pi->alt) { buf[0] = *cp++; buf[1] = *decimal_point; ret += __printf_puts(io, buf, 2); ret += __printf_puts(io, cp, ndig - 1); ret += __printf_pad(io, prec - ndig, 1); } else { /* XeYYY */ ret += __printf_puts(io, cp, 1); } ret += __printf_puts(io, expstr, expsize); } } /* left-adjusting padding (always blank) */ if (pi->left) { ret += __printf_pad(io, pi->width - realsz, 0); } __printf_flush(io); if (dtoaresult != NULL) { freedtoa(dtoaresult); } return (ret); }
template <class I, class CAT> struct hypot_ctnts<simd::native<double, CAT>, I> { typedef I int_type; static inline int_type C1(){ return boost::simd::integral_constant<int_type, 500>();}; static inline int_type C2(){ return boost::simd::integral_constant<int_type, 600>();}; static inline int_type MC1(){ return boost::simd::integral_constant<int_type, -500>();}; static inline int_type MC2(){ return boost::simd::integral_constant<int_type, -600>();}; static inline int_type C3(){ return boost::simd::integral_constant<int_type, 0x0010000000000000ll>();} static inline int_type M1(){ return boost::simd::integral_constant<int_type, 0xffffffff00000000ll>();}; }; typedef typename dispatch::meta::as_floating<A0>::type result_type; BOOST_SIMD_FUNCTOR_CALL_REPEAT(2) { typedef typename dispatch::meta::as_integer<result_type>::type itype; result_type r = boost::simd::abs(a0); result_type i = boost::simd::abs(a1); itype e = exponent(boost::simd::max(i, r)); return if_else( logical_or(logical_and(is_nan(a0), is_inf(a1)), logical_and(is_nan(a1), is_inf(a0))), Inf<result_type>(), ldexp(sqrt(sqr(ldexp(r, -e))+sqr(ldexp(i, -e))), e) ); } }; } } } #endif
bignum root(const bignum &nth_root, const bignum &base_number, int decimal_places) { //std::cout << "root calc" << std::endl; if (nth_root.getBase() != base_number.getBase()) return root(nth_root, base_number.getConverted(nth_root.getBase()), decimal_places); //TODO: verify that the 2.5th root of -2 is irrational, if (base_number.isNegative()) { if (nth_root.getDecimalCount() > 0 || nth_root % 2 == 0) throw error_handler(__FILE__, __LINE__, "The program attempted to compute an irrational value"); else return root(nth_root, base_number.absolute(), decimal_places) * -1; } if (nth_root.isNegative()) { bignum one(1); one.setBase(base_number.getBase()); return root(nth_root.absolute(), one / base_number, decimal_places); } if (base_number == 0 || base_number == 1) return base_number; //cross-checks the root being tested to the precision threshold specified bignum precision_check(1); precision_check.setBase(nth_root.getBase()); precision_check.rightShift(decimal_places); bignum range_low = base_number - precision_check; bignum range_high = base_number + precision_check; bignum root_test; root_test = base_number < 1 ? base_number * nth_root : base_number / nth_root; //TODO: refine increment function to scale depending on the size of the number being tested bignum increment(1); increment.setBase(nth_root.getBase()); if (base_number < 1) increment.rightShift(1); bignum answer_check; answer_check.setBase(nth_root.getBase()); //sets once function finds general region of the answer bool approximate = false; for (;;) { //adjusts number precision to check for nearest round roots //prevents function from returning 3.99999 instead of 4 if (!approximate) root_test.roundToIndex(ONES_PLACE - increment.getDecimalCount()); answer_check = exponent(root_test, nth_root); if (answer_check > range_low && answer_check < range_high) return root_test; if (answer_check > base_number) { if (approximate) { root_test -= increment; increment.rightShift(1); root_test += increment; } else root_test /= nth_root; } else if (answer_check < base_number) { if (!approximate) approximate = true; root_test += increment; } } }
/* Limited measurements show no results worse than 64 bit precision except for the results for arguments close to 2^63, where the precision of the result sometimes degrades to about 63.9 bits */ static int trig_arg(FPU_REG *st0_ptr, int even) { FPU_REG tmp; u_char tmptag; unsigned long long q; int old_cw = control_word, saved_status = partial_status; int tag, st0_tag = TAG_Valid; if ( exponent(st0_ptr) >= 63 ) { partial_status |= SW_C2; /* Reduction incomplete. */ return -1; } control_word &= ~CW_RC; control_word |= RC_CHOP; setpositive(st0_ptr); tag = FPU_u_div(st0_ptr, &CONST_PI2, &tmp, PR_64_BITS | RC_CHOP | 0x3f, SIGN_POS); FPU_round_to_int(&tmp, tag); /* Fortunately, this can't overflow to 2^64 */ q = significand(&tmp); if ( q ) { rem_kernel(significand(st0_ptr), &significand(&tmp), significand(&CONST_PI2), q, exponent(st0_ptr) - exponent(&CONST_PI2)); setexponent16(&tmp, exponent(&CONST_PI2)); st0_tag = FPU_normalize(&tmp); FPU_copy_to_reg0(&tmp, st0_tag); } if ( (even && !(q & 1)) || (!even && (q & 1)) ) { st0_tag = FPU_sub(REV|LOADED|TAG_Valid, (int)&CONST_PI2, FULL_PRECISION); #ifdef BETTER_THAN_486 /* So far, the results are exact but based upon a 64 bit precision approximation to pi/2. The technique used now is equivalent to using an approximation to pi/2 which is accurate to about 128 bits. */ if ( (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64) || (q > 1) ) { /* This code gives the effect of having pi/2 to better than 128 bits precision. */ significand(&tmp) = q + 1; setexponent16(&tmp, 63); FPU_normalize(&tmp); tmptag = FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, SIGN_POS, exponent(&CONST_PI2extra) + exponent(&tmp)); setsign(&tmp, getsign(&CONST_PI2extra)); st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION); if ( signnegative(st0_ptr) ) { /* CONST_PI2extra is negative, so the result of the addition can be negative. This means that the argument is actually in a different quadrant. The correction is always < pi/2, so it can't overflow into yet another quadrant. */ setpositive(st0_ptr); q++; } } #endif BETTER_THAN_486 } #ifdef BETTER_THAN_486 else { /* So far, the results are exact but based upon a 64 bit precision approximation to pi/2. The technique used now is equivalent to using an approximation to pi/2 which is accurate to about 128 bits. */ if ( ((q > 0) && (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64)) || (q > 1) ) { /* This code gives the effect of having p/2 to better than 128 bits precision. */ significand(&tmp) = q; setexponent16(&tmp, 63); FPU_normalize(&tmp); /* This must return TAG_Valid */ tmptag = FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, SIGN_POS, exponent(&CONST_PI2extra) + exponent(&tmp)); setsign(&tmp, getsign(&CONST_PI2extra)); st0_tag = FPU_sub(LOADED|(tmptag & 0x0f), (int)&tmp, FULL_PRECISION); if ( (exponent(st0_ptr) == exponent(&CONST_PI2)) && ((st0_ptr->sigh > CONST_PI2.sigh) || ((st0_ptr->sigh == CONST_PI2.sigh) && (st0_ptr->sigl > CONST_PI2.sigl))) ) { /* CONST_PI2extra is negative, so the result of the subtraction can be larger than pi/2. This means that the argument is actually in a different quadrant. The correction is always < pi/2, so it can't overflow into yet another quadrant. */ st0_tag = FPU_sub(REV|LOADED|TAG_Valid, (int)&CONST_PI2, FULL_PRECISION); q++; } } } #endif BETTER_THAN_486 FPU_settag0(st0_tag); control_word = old_cw; partial_status = saved_status & ~SW_C2; /* Reduction complete. */ return (q & 3) | even; }
int main(void) { char a, o; int flush, r; float digits_a, digits_b; flush = r = 0; digits_a = digits_b = 0; do { digits_a = get_operand(); o = get_operator(); while (o != 'c') { digits_b = get_operand(); switch(o) { case '+': r = add(digits_a, digits_b); break; case '-': r = subtract(digits_a, digits_b); case '*': r = multiply(digits_a, digits_b); break; case '/': r = division(digits_a, digits_b); break; case 'e': r = exponent(digits_a, digits_b); break; default: printf("\nINVALID OPERATOR\n"); break; } /* end of SWITCH */ printf("\n\nResult = %d\n",r); digits_a = r; o = get_operator(); } /* while o != clear */ printf("\nEnter n to quit, or\n"); printf("enter y to do another operation: "); a = getchar(); if (a == 'y') { while (flush != '\n') { flush = getchar(); } } }while (a == 'y'); return 0; }
Quaternion Quaternion::determineQi(const Quaternion& aiminus1, const Quaternion& ai, const Quaternion& aiplus1) { Quaternion temp = -(log(ai.inverse()*aiplus1) + log(ai.inverse()*aiminus1))/4.0; Quaternion qi = ai * exponent(temp); return qi; }
int main() { printf("%d ", exponent(2,3)); gets(); return 0; }
static int compare(FPU_REG const *b, int tagb) { int diff, exp0, expb; u_char st0_tag; FPU_REG *st0_ptr; FPU_REG x, y; u_char st0_sign, signb = getsign(b); st0_ptr = &st(0); st0_tag = FPU_gettag0(); st0_sign = getsign(st0_ptr); if (tagb == TAG_Special) tagb = FPU_Special(b); if (st0_tag == TAG_Special) st0_tag = FPU_Special(st0_ptr); if (((st0_tag != TAG_Valid) && (st0_tag != TW_Denormal)) || ((tagb != TAG_Valid) && (tagb != TW_Denormal))) { if (st0_tag == TAG_Zero) { if (tagb == TAG_Zero) return COMP_A_eq_B; if (tagb == TAG_Valid) return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B); if (tagb == TW_Denormal) return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B) | COMP_Denormal; } else if (tagb == TAG_Zero) { if (st0_tag == TAG_Valid) return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B); if (st0_tag == TW_Denormal) return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B) | COMP_Denormal; } if (st0_tag == TW_Infinity) { if ((tagb == TAG_Valid) || (tagb == TAG_Zero)) return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B); else if (tagb == TW_Denormal) return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B) | COMP_Denormal; else if (tagb == TW_Infinity) { /* */ return (st0_sign == signb) ? COMP_A_eq_B : ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B); } /* */ } else if (tagb == TW_Infinity) { if ((st0_tag == TAG_Valid) || (st0_tag == TAG_Zero)) return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B); if (st0_tag == TW_Denormal) return ((signb == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B) | COMP_Denormal; /* */ } /* */ if ((st0_tag == TW_NaN) || (tagb == TW_NaN)) { int signalling = 0, unsupported = 0; if (st0_tag == TW_NaN) { signalling = (st0_ptr->sigh & 0xc0000000) == 0x80000000; unsupported = !((exponent(st0_ptr) == EXP_OVER) && (st0_ptr-> sigh & 0x80000000)); } if (tagb == TW_NaN) { signalling |= (b->sigh & 0xc0000000) == 0x80000000; unsupported |= !((exponent(b) == EXP_OVER) && (b->sigh & 0x80000000)); } if (signalling || unsupported) return COMP_No_Comp | COMP_SNaN | COMP_NaN; else /* */ return COMP_No_Comp | COMP_NaN; } EXCEPTION(EX_Invalid); } if (st0_sign != signb) { return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B) | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ? COMP_Denormal : 0); } if ((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) { FPU_to_exp16(st0_ptr, &x); FPU_to_exp16(b, &y); st0_ptr = &x; b = &y; exp0 = exponent16(st0_ptr); expb = exponent16(b); } else { exp0 = exponent(st0_ptr); expb = exponent(b); } #ifdef PARANOID if (!(st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid); if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid); #endif /* */ diff = exp0 - expb; if (diff == 0) { diff = st0_ptr->sigh - b->sigh; /* */ if (diff == 0) { diff = st0_ptr->sigl > b->sigl; if (diff == 0) diff = -(st0_ptr->sigl < b->sigl); } } if (diff > 0) { return ((st0_sign == SIGN_POS) ? COMP_A_gt_B : COMP_A_lt_B) | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ? COMP_Denormal : 0); } if (diff < 0) { return ((st0_sign == SIGN_POS) ? COMP_A_lt_B : COMP_A_gt_B) | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ? COMP_Denormal : 0); } return COMP_A_eq_B | (((st0_tag == TW_Denormal) || (tagb == TW_Denormal)) ? COMP_Denormal : 0); }
void blur_gauss_y(u64 size,u64 radius,u8* src,u8* dst) { int x,y; int m,n; int width,height; double sigma; double temp; double r,g,b; //由公式:d = 6σ + 1,可以得到σ = r / 3. if(radius>9)radius=9; sigma=(double)radius; sigma/=3; //say("radius=%lld,sigma=%lf\n",radius,sigma); //first build the "gauss table" for(y=0;y<=radius;y++) { temp = (double)(-y*y); temp /= 2*sigma*sigma; gausstable[0][y] = exponent(temp); gausstable[0][y] /= sigma*squareroot(2*pi); //say("gausstable[%d]=%lf\n",y,gausstable[0][y]); } //开始 width=size&0xffff; height=(size>>16)&0xffff; for(y=radius;y<height-radius;y++) { for(x=radius;x<width-radius;x++) { //process this pixel r=g=b=0.0; //<0 for(m=-radius;m<0;m++) { // temp=gausstable[0][-m]; //b b+=temp*(double)src[ ( (width*(y+m) + x )<<2)+0]; //g g+=temp*(double)src[ ( (width*(y+m) + x )<<2)+1]; //r r+=temp*(double)src[ ( (width*(y+m) + x )<<2)+2]; }//m //>0 for(m=0;m<radius;m++) { // temp=gausstable[0][m]; //b b+=temp*(double)src[ ( (width*(y+m) + x )<<2)+0]; //g g+=temp*(double)src[ ( (width*(y+m) + x )<<2)+1]; //r r+=temp*(double)src[ ( (width*(y+m) + x )<<2)+2]; }//m //put the result //say("(%d,%d):%lf,%lf,%lf\n",x,y,b,g,r); dst[((width*y+x)<<2)+0]=(int)b; dst[((width*y+x)<<2)+1]=(int)g; dst[((width*y+x)<<2)+2]=(int)r; }//x }//y }
int Naive(int *a, int n, int x) { if (n==0) return a[n]; int s = Naive(a, n-1, x) + a[n]*exponent(x,n); return s; }
void bignum::convertBase(int n) { if (isZero()) { base = n; return; } bool original_negative = negative; bignum toAdd; bignum temp(0); temp.setBase(n); bignum original_ten(10); original_ten.setBase(base); bignum converted_ten(original_ten); converted_ten.convertBaseSimple(n); bignum original_nth; bignum converted_nth; if (base != n) { for (int i = 0; i < digitRange; i++) { int index(left_most - i); if (i == 0) { original_nth = bignum(index - ONES_PLACE); original_nth.convertBaseSimple(base); converted_nth = bignum(original_nth); converted_nth.convertBaseSimple(n); } else converted_nth--; if (index >= MAXDIGITS) throw error_handler(__FILE__, __LINE__, "The value being calculated is too large for the settings provided"); if (index < 0) break; //each digit of the number is evaluated evaluated X * 10^n format bignum original_digit(getDigit(index)); if (original_digit.isZero()) continue; original_digit.convertBaseSimple(base); //each of the above format is converted simply bignum converted_digit(original_digit); converted_digit.convertBaseSimple(n); //add X * 10^n to the solution bignum multiplier(exponent(converted_ten, converted_nth)); bignum toAdd = converted_digit * multiplier; temp += toAdd; } *this = temp; } negative = original_negative; updateDigits(); }
static void fptan(FPU_REG *st0_ptr, u_char st0_tag) { FPU_REG *st_new_ptr; int q; u_char arg_sign = getsign(st0_ptr); /* Stack underflow has higher priority */ if ( st0_tag == TAG_Empty ) { FPU_stack_underflow(); /* Puts a QNaN in st(0) */ if ( control_word & CW_Invalid ) { st_new_ptr = &st(-1); push(); FPU_stack_underflow(); /* Puts a QNaN in the new st(0) */ } return; } if ( STACK_OVERFLOW ) { FPU_stack_overflow(); return; } if ( st0_tag == TAG_Valid ) { if ( exponent(st0_ptr) > -40 ) { if ( (q = trig_arg(st0_ptr, 0)) == -1 ) { /* Operand is out of range */ return; } poly_tan(st0_ptr); setsign(st0_ptr, (q & 1) ^ (arg_sign != 0)); set_precision_flag_up(); /* We do not really know if up or down */ } else { /* For a small arg, the result == the argument */ /* Underflow may happen */ denormal_arg: FPU_to_exp16(st0_ptr, st0_ptr); st0_tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign); FPU_settag0(st0_tag); } push(); FPU_copy_to_reg0(&CONST_1, TAG_Valid); return; } if ( st0_tag == TAG_Zero ) { push(); FPU_copy_to_reg0(&CONST_1, TAG_Valid); setcc(0); return; } if ( st0_tag == TAG_Special ) st0_tag = FPU_Special(st0_ptr); if ( st0_tag == TW_Denormal ) { if ( denormal_operand() < 0 ) return; goto denormal_arg; } if ( st0_tag == TW_Infinity ) { /* The 80486 treats infinity as an invalid operand */ if ( arith_invalid(0) >= 0 ) { st_new_ptr = &st(-1); push(); arith_invalid(0); } return; } single_arg_2_error(st0_ptr, st0_tag); }
int main(int argc, char *argv[]){ int i=0,length=0; unsigned long long int sc=0,st=0; int b1=atoi(argv[1]); int b2=atoi(argv[2]); while(argv[3][length]!='\0') length++; if(b1==2) for(i=0;i<length;i++) if(argv[3][i]=='1'||argv[3][i]=='0') st=st+(argv[3][i]-48)*exponent(2,length-i-1); else{ printf("0"); return 0; } else if(b1==8) for(i=0;i<length;i++) if(argv[3][i]<=55&&argv[3][i]>=48) st=st+(argv[3][i]-48)*exponent(8,length-i-1); else{ printf("0"); return 0; } else if(b1==16) for(i=0;i<length;i++) if(argv[3][i]<=57&&argv[3][i]>=48) st=st+(argv[3][i]-48)*exponent(16,length-i-1); else if(argv[3][i]<=70&&argv[3][i]>=65) st=st+(argv[3][i]-55)*exponent(16,length-i-1); else{ printf("0"); return 0; } else if(b1==10) for(i=0;i<length;i++) if(argv[3][i]<=57&&argv[3][i]>=48) st=10*st+(argv[3][i]-48); else{ printf("0"); return 0; } else{ printf("0"); return 0; } if(b2==10){ sc=st; length=0; while(st>0){ length++; st=st/10; } char M[length-1]; for(i=0;sc>0;i++,sc=sc/10) M[i]=(sc%10)+'0'; for(length=0;length<i;length++) putchar(M[i-length-1]); } else if(b2==8){ sc=st; length=0; while(st>0){ length++; st=st/8; } char M[length-1]; for(i=0;sc>0;i++,sc=sc/8) M[i]=(sc%8)+'0'; for(length=0;length<i;length++) putchar(M[i-length-1]); } else if(b2==16){ sc=st; length=0; while(st>0){ length++; st=st/16; } char M[length-1]; for(i=0;sc>0;i++,sc=sc/16){ if((sc%16)<10) M[i]=(sc%16)+'0'; else M[i]=(sc%16)+55; } for(length=0;length<i;length++) putchar(M[i-length-1]); } else if(b2==2){ sc=st; length=0; while(st>0){ length++; st=st/2; } char M[length-1]; for(i=0;sc>0;i++,sc=sc/2) M[i]=(sc%2)+'0'; for(length=0;length<i;length++) putchar(M[i-length-1]); } else printf("0"); return 0; }
static void fxtract(FPU_REG *st0_ptr, u_char st0_tag) { FPU_REG *st_new_ptr; u_char sign; register FPU_REG *st1_ptr = st0_ptr; /* anticipate */ if ( STACK_OVERFLOW ) { FPU_stack_overflow(); return; } clear_C1(); if ( st0_tag == TAG_Valid ) { long e; push(); sign = getsign(st1_ptr); reg_copy(st1_ptr, st_new_ptr); setexponent16(st_new_ptr, exponent(st_new_ptr)); denormal_arg: e = exponent16(st_new_ptr); convert_l2reg(&e, 1); setexponentpos(st_new_ptr, 0); setsign(st_new_ptr, sign); FPU_settag0(TAG_Valid); /* Needed if arg was a denormal */ return; } else if ( st0_tag == TAG_Zero ) { sign = getsign(st0_ptr); if ( FPU_divide_by_zero(0, SIGN_NEG) < 0 ) return; push(); FPU_copy_to_reg0(&CONST_Z, TAG_Zero); setsign(st_new_ptr, sign); return; } if ( st0_tag == TAG_Special ) st0_tag = FPU_Special(st0_ptr); if ( st0_tag == TW_Denormal ) { if (denormal_operand() < 0 ) return; push(); sign = getsign(st1_ptr); FPU_to_exp16(st1_ptr, st_new_ptr); goto denormal_arg; } else if ( st0_tag == TW_Infinity ) { sign = getsign(st0_ptr); setpositive(st0_ptr); push(); FPU_copy_to_reg0(&CONST_INF, TAG_Special); setsign(st_new_ptr, sign); return; } else if ( st0_tag == TW_NaN ) { if ( real_1op_NaN(st0_ptr) < 0 ) return; push(); FPU_copy_to_reg0(st0_ptr, TAG_Special); return; } else if ( st0_tag == TAG_Empty ) { /* Is this the correct behaviour? */ if ( control_word & EX_Invalid ) { FPU_stack_underflow(); push(); FPU_stack_underflow(); } else EXCEPTION(EX_StackUnder); } #ifdef PARANOID else EXCEPTION(EX_INTERNAL | 0x119); #endif PARANOID }
int cwt_vsnprintf(CWT_CHAR *string, size_t length, const CWT_CHAR *format, va_list args) { struct DATA data; CWT_CHAR conv_field[MAX_FIELD]; double d; /* temporary holder */ int state; int i; data.length = length - 1; /* leave room for '\0' */ data.holder = string; data.pf = format; data.counter = 0; /* sanity check, the string must be > 1 */ if (length < 1) return -1; for (; *data.pf && (data.counter < data.length); data.pf++) { if ( *data.pf == _T('%') ) { /* we got a magic % cookie */ conv_flag((CWT_CHAR *)0, &data); /* initialise format flags */ for (state = 1; *data.pf && state;) { switch (*(++data.pf)) { case _T('\0'): /* a NULL here ? ? bail out */ *data.holder = _T('\0'); return data.counter; break; case _T('f'): /* float, double */ STAR_ARGS(&data); d = va_arg(args, double); floating(&data, d); state = 0; break; case _T('g'): case _T('G'): STAR_ARGS(&data); DEF_PREC(&data); d = va_arg(args, double); i = log_10(d); /* for '%g|%G' ANSI: use f if exponent * is in the range or [-4,p] exclusively * else use %e|%E */ if (-4 < i && i < data.precision) floating(&data, d); else exponent(&data, d); state = 0; break; case _T('e'): case _T('E'): /* Exponent double */ STAR_ARGS(&data); d = va_arg(args, double); exponent(&data, d); state = 0; break; case _T('u'): case _T('d'): /* decimal */ STAR_ARGS(&data); if (data.a_long == FOUND) d = va_arg(args, long); else d = va_arg(args, int); decimal(&data, d); state = 0; break; case _T('o'): /* octal */ STAR_ARGS(&data); if (data.a_long == FOUND) d = va_arg(args, long); else d = va_arg(args, int); octal(&data, d); state = 0; break; case _T('x'): case _T('X'): /* hexadecimal */ STAR_ARGS(&data); if (data.a_long == FOUND) d = va_arg(args, long); else d = va_arg(args, int); hexa(&data, d); state = 0; break; case _T('c'): /* character */ d = va_arg(args, int); PUT_CHAR((CWT_CHAR)d, &data); state = 0; break; case _T('s'): /* string */ STAR_ARGS(&data); strings(&data, va_arg(args, CWT_CHAR *)); state = 0; break; case _T('n'): *(va_arg(args, int *)) = data.counter; /* what's the count ? */ state = 0; break; case _T('l'): data.a_long = FOUND; break; case _T('h'): break; case _T('%'): /* nothing just % */ PUT_CHAR(_T('%'), &data); state = 0; break; case _T('#'): case _T(' '): case _T('+'): case _T('*'): case _T('-'): case _T('.'): case _T('0'): case _T('1'): case _T('2'): case _T('3'): case _T('4'): case _T('5'): case _T('6'): case _T('7'): case _T('8'): case _T('9'): /* initialize width and precision */ for (i = 0; isflag(*data.pf); i++, data.pf++) if (i < MAX_FIELD - 1) conv_field[i] = *data.pf; conv_field[i] = _T('\0'); conv_flag(conv_field, &data); data.pf--; /* went to far go back */ break; default: /* is this an error ? maybe bail out */ state = 0; break; } /* end switch */
void priv_pub(unsigned char QUAD[37][37][37], unsigned char LIN[37][37], unsigned char CONS[37], unsigned char S1[37][37],unsigned char S2[37], unsigned char T1[37][37],unsigned char T2[37], unsigned char M[16384]) { int i,j,k,l,m; unsigned char X[37], Y[37], EXP[37][37], QUAD3[37][37][37], LIN3[37][37], CONS3[37]; unsigned char expo3[78] /*128^11 */ = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; for(i=0;i<37;i++) /* Construction de ^ (256^11) */ { memset(X,0,37); X[i] = 1; exponent(EXP[i],X,expo3,78,M); } for(i=0; i<37; i++) /* Construction de la forme quad produit */ { memset(X,0,37); X[i] = 1; for(j=0; j<37; j++) { memset(Y,0,37); Y[j] = 1; mul37(QUAD3[i][j],X,Y,M); } } for(i=0;i<37;i++) /* Compos‚e des 2*/ { for(j=0;j<37;j++) { for(k=0;k<37;k++) { QUAD[i][j][k] = 0; } } } for(i=0;i<37;i++) { for(j=0;j<37;j++) { for(k=0;k<37;k++) { for(l=0;l<37;l++) { QUAD[l][j][k] ^= M[(((unsigned long) EXP[j][i])<<7) + (unsigned long) QUAD3[i][k][l]]; } } } } for(i=0; i<37; i++) { CONS3[i]=0; for(j=0; j<37; j++) { LIN3[i][j]=0; for(k=0; k<37; k++) { QUAD3[i][j][k]=0; } } } for(i=0; i<37; i++) { for(j=0; j<37; j++) { for(k=0; k<37; k++) { CONS3[i] ^= M[(((unsigned long) QUAD[i][j][k])<<7) + (unsigned long) M[(((unsigned long) S2[j])<<7) + (unsigned long) S2[k]]]; for(l=0; l<37; l++) { LIN3[i][l] ^= M[(((unsigned long) QUAD[i][j][k])<<7) + (unsigned long) M[(((unsigned long) S2[j])<<7) + (unsigned long) S1[l][k]]]; LIN3[i][l] ^= M[(((unsigned long) QUAD[i][j][k])<<7) + (unsigned long) M[(((unsigned long) S2[k])<<7) + (unsigned long) S1[l][j]]]; } for(l=0; l<37; l++) { for(m=0; m<37; m++) { QUAD3[i][l][m] ^= M[(((unsigned long) QUAD[i][j][k])<<7) + (unsigned long) M[(((unsigned long) S1[l][j])<<7) + (unsigned long) S1[m][k]]]; } } } } } for(i=0; i<37; i++) { CONS[i]=0; for(j=0; j<37; j++) { LIN[i][j]=0; for(k=0; k<37; k++) { QUAD[i][j][k]=0; } } } for(i=0;i<37;i++) { CONS[i] ^= T2[i]; for(j=0;j<37;j++) { CONS[i] ^= M[(((unsigned long) CONS3[j])<<7) + (unsigned long) T1[j][i]]; for(k=0;k<37;k++) { LIN[i][k] ^= M[(((unsigned long) LIN3[j][k])<<7) + (unsigned long) T1[j][i]]; for(l=0;l<37;l++) { QUAD[i][k][l] ^= M[(((unsigned long) QUAD3[j][k][l])<<7) +(unsigned long) T1[j][i]]; } } } } for(i=0;i<37;i++) /* regroupement des termes symetriques, attention a ne pas laisser j a la place de j+1 */ { for(j=0;j<37;j++) { for(k=j+1;k<37;k++) { QUAD[i][j][k] ^= QUAD[i][k][j]; } } } }
/* Operates on st(0) and st(n), or on st(0) and temporary data. The destination must be one of the source st(x). */ int FPU_add(FPU_REG const *b, u_char tagb, int deststnr, int control_w) { FPU_REG *a = &st(0); FPU_REG *dest = &st(deststnr); u_char signb = getsign(b); u_char taga = FPU_gettag0(); u_char signa = getsign(a); u_char saved_sign = getsign(dest); int diff, tag, expa, expb; if ( !(taga | tagb) ) { expa = exponent(a); expb = exponent(b); valid_add: /* Both registers are valid */ if (!(signa ^ signb)) { /* signs are the same */ tag = FPU_u_add(a, b, dest, control_w, signa, expa, expb); } else { /* The signs are different, so do a subtraction */ diff = expa - expb; if (!diff) { diff = a->sigh - b->sigh; /* This works only if the ms bits are identical. */ if (!diff) { diff = a->sigl > b->sigl; if (!diff) diff = -(a->sigl < b->sigl); } } if (diff > 0) { tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb); } else if ( diff < 0 ) { tag = FPU_u_sub(b, a, dest, control_w, signb, expb, expa); } else { FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr); /* sign depends upon rounding mode */ setsign(dest, ((control_w & CW_RC) != RC_DOWN) ? SIGN_POS : SIGN_NEG); return TAG_Zero; } } if ( tag < 0 ) { setsign(dest, saved_sign); return tag; } FPU_settagi(deststnr, tag); return tag; } if ( taga == TAG_Special ) taga = FPU_Special(a); if ( tagb == TAG_Special ) tagb = FPU_Special(b); if ( ((taga == TAG_Valid) && (tagb == TW_Denormal)) || ((taga == TW_Denormal) && (tagb == TAG_Valid)) || ((taga == TW_Denormal) && (tagb == TW_Denormal)) ) { FPU_REG x, y; if ( denormal_operand() < 0 ) return FPU_Exception; FPU_to_exp16(a, &x); FPU_to_exp16(b, &y); a = &x; b = &y; expa = exponent16(a); expb = exponent16(b); goto valid_add; } if ( (taga == TW_NaN) || (tagb == TW_NaN) ) { if ( deststnr == 0 ) return real_2op_NaN(b, tagb, deststnr, a); else return real_2op_NaN(a, taga, deststnr, a); } return add_sub_specials(a, taga, signa, b, tagb, signb, dest, deststnr, control_w); }
void operator()(std::map<uint64_t, uint64_t> &accounts, std::string thread_seed) { // Our approach is to pick a random point and repeatedly double it. // This is cheaper than the more naive approach of multiplying the // generator point times random exponents. // We work in batches because our point doubling algorithm requires a // modular inversion which is more efficiently computed in batches. const int n = BATCH_SIZE; felem xs[BATCH_SIZE], zs[BATCH_SIZE]; std::vector<bytestring> exponents; static const unsigned char generator[32] = {9}; for ( int i = 0; i < n; i++ ) { bytestring exponent(32, 0); std::string exponent_seed = boost::str(boost::format("%1%:%2%") % thread_seed % i); sha256((unsigned char*) &exponent_seed[0], exponent_seed.size(), &exponent[0]); // transform initial exponent according to curve25519 tweaks exponent[0] &= 248; exponent[31] &= 127; exponent[31] |= 64; uint8_t pubkey[32]; curve25519_donna(pubkey, &exponent[0], generator); fexpand(xs[i], pubkey); exponents.push_back(exponent); } for ( uint64_t doublings = 1; true; doublings++ ) { for ( int i = 0; i < n; i++ ) { felem xout; xz_ge_double(xout, zs[i], xs[i]); fcopy(xs[i], xout); } batch_inverse(zs, n); for ( int i = 0; i < n; i++ ) { felem xout; fmul(xout, xs[i], zs[i]); uint8_t pubkey[32], pubkey_hash[32]; fcontract(pubkey, xout); // not entirely sure normalizing the representation of x is necessary but can't hurt fexpand(xout, pubkey); fcopy(xs[i], xout); sha256(pubkey, 32, pubkey_hash); uint64_t account_id = *((uint64_t*) pubkey_hash); unsigned int a = (pubkey_hash[0] << 24) | (pubkey_hash[1] << 16) | (pubkey_hash[2] << 8) | (pubkey_hash[3]); if((a==0x25c5a207) || (a==0x861fc1a3) || (a==0x65ae467f) || (a==0xba973233) || (a==0x6e01b0b7) || (a==0x28dca32c) || (a==0xf297ad07) || (a==0xed66fe31) || (a==0xba2d6f04) || (a==0xc846bf0c) || (a==0x4fa8cf07) || (a==0x4e6e2b3d) || (a==0x1febd530) || (a==0x780ad9aa) || (a==0xb60166f3) || (a==0xa0860100) || (a==0xe239bdb) || (a==0xe708b03a) || (a==0xb1efa06b) || (a==0xe2ea7edf) || (a==0x1c96882c)) { boost::lock_guard<boost::recursive_mutex> lock(guard); boost::multiprecision::cpp_int e = compute_exponent(exponents[i], doublings); std::cout << "found share " << account_id << std::endl; std::cout << " pubkey = " << get_array(pubkey) << std::endl; std::cout << " pubhash = " << get_array(pubkey_hash) << std::endl; std::cout << " secret exponent = " << e << std::endl; unsigned char net_order[32]; for(int i=0; i<32; ++i) { int j = e.convert_to<int>(); net_order[31-i] = j & 0xFF; e = e >> 8; } submit_share(account,get_array(net_order)); } } checked += n; }
int isNaN(FPU_REG const *ptr) { return ((exponent(ptr) == EXP_BIAS + EXP_OVER) && !((ptr->sigh == 0x80000000) && (ptr->sigl == 0))); }
/* Subtract b from a. (a-b) -> dest */ int FPU_sub(int flags, int rm, int control_w) { FPU_REG const *a, *b; FPU_REG *dest; u_char taga, tagb, signa, signb, saved_sign, sign; int diff, tag = 0, expa, expb, deststnr; a = &st(0); taga = FPU_gettag0(); deststnr = 0; if (flags & LOADED) { b = (FPU_REG *) rm; tagb = flags & 0x0f; } else { b = &st(rm); tagb = FPU_gettagi(rm); if (flags & DEST_RM) deststnr = rm; } signa = getsign(a); signb = getsign(b); if (flags & REV) { signa ^= SIGN_NEG; signb ^= SIGN_NEG; } dest = &st(deststnr); saved_sign = getsign(dest); if (!(taga | tagb)) { expa = exponent(a); expb = exponent(b); valid_subtract: /* Both registers are valid */ diff = expa - expb; if (!diff) { diff = a->sigh - b->sigh; /* Works only if ms bits are identical */ if (!diff) { diff = a->sigl > b->sigl; if (!diff) diff = -(a->sigl < b->sigl); } } switch ((((int)signa) * 2 + signb) / SIGN_NEG) { case 0: /* P - P */ case 3: /* N - N */ if (diff > 0) { /* |a| > |b| */ tag = FPU_u_sub(a, b, dest, control_w, signa, expa, expb); } else if (diff == 0) { FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr); /* sign depends upon rounding mode */ setsign(dest, ((control_w & CW_RC) != RC_DOWN) ? SIGN_POS : SIGN_NEG); return TAG_Zero; } else { sign = signa ^ SIGN_NEG; tag = FPU_u_sub(b, a, dest, control_w, sign, expb, expa); } break; case 1: /* P - N */ tag = FPU_u_add(a, b, dest, control_w, SIGN_POS, expa, expb); break; case 2: /* N - P */ tag = FPU_u_add(a, b, dest, control_w, SIGN_NEG, expa, expb); break; #ifdef PARANOID default: EXCEPTION(EX_INTERNAL | 0x111); return -1; #endif } if (tag < 0) { setsign(dest, saved_sign); return tag; } FPU_settagi(deststnr, tag); return tag; } if (taga == TAG_Special) taga = FPU_Special(a); if (tagb == TAG_Special) tagb = FPU_Special(b); if (((taga == TAG_Valid) && (tagb == TW_Denormal)) || ((taga == TW_Denormal) && (tagb == TAG_Valid)) || ((taga == TW_Denormal) && (tagb == TW_Denormal))) { FPU_REG x, y; if (denormal_operand() < 0) return FPU_Exception; FPU_to_exp16(a, &x); FPU_to_exp16(b, &y); a = &x; b = &y; expa = exponent16(a); expb = exponent16(b); goto valid_subtract; } if ((taga == TW_NaN) || (tagb == TW_NaN)) { FPU_REG const *d1, *d2; if (flags & REV) { d1 = b; d2 = a; } else { d1 = a; d2 = b; } if (flags & LOADED) return real_2op_NaN(b, tagb, deststnr, d1); if (flags & DEST_RM) return real_2op_NaN(a, taga, deststnr, d2); else return real_2op_NaN(b, tagb, deststnr, d2); } return add_sub_specials(a, taga, signa, b, tagb, signb ^ SIGN_NEG, dest, deststnr, control_w); }
static void lib_dtoa(FAR struct lib_outstream_s *obj, int ch, int prec, uint8_t flags, double _double) { FAR char *cp; /* Handy char pointer (short term usage) */ FAR char *cp_free = NULL; /* BIONIC: copy of cp to be freed after usage */ char expstr[7]; /* Buffer for exponent string */ char sign; /* Temporary negative sign for floats */ int expt; /* Integer value of exponent */ int expsize = 0; /* Character count for expstr */ int ndig; /* Actual number of digits returned by cvt */ int size; /* Size of converted field or string */ int i; cp = cvt(_double, prec, flags, &sign, &expt, ch, &ndig); cp_free = cp; if (ch == 'g' || ch == 'G') { /* 'g' or 'G' fmt */ if (expt <= -4 || expt > prec) { ch = (ch == 'g') ? 'e' : 'E'; } else { ch = 'g'; } } if (ch <= 'e') { /* 'e' or 'E' fmt */ --expt; expsize = exponent(expstr, expt, ch); size = expsize + ndig; if (ndig > 1 || IS_ALTFORM(flags)) { ++size; } } else if (ch == 'f') { /* f fmt */ if (expt > 0) { size = expt; if (prec || IS_ALTFORM(flags)) { size += prec + 1; } } else /* "0.X" */ { size = prec + 2; } } else if (expt >= ndig) { /* fixed g fmt */ size = expt; if (IS_ALTFORM(flags)) { ++size; } } else { size = ndig + (expt > 0 ? 1 : 2 - expt); } if (sign) { obj->put(obj, '-'); } if (_double == 0) { /* kludge for __dtoa irregularity */ obj->put(obj, '0'); if (expt < ndig || IS_ALTFORM(flags)) { obj->put(obj, '.'); i = ndig - 1; while (i > 0) { obj->put(obj, '0'); i--; } } } else if (expt <= 0) { obj->put(obj, '0'); obj->put(obj, '.'); i = ndig; while (i > 0) { obj->put(obj, *cp); i--; cp++; } } else if (expt >= ndig) { i = ndig; while (i > 0) { obj->put(obj, *cp); i--; cp++; } i = expt - ndig; while (i > 0) { obj->put(obj, '0'); i--; } if (IS_ALTFORM(flags)) { obj->put(obj, '.'); } } else { /* print the integer */ i = expt; while (i > 0) { obj->put(obj, *cp); i--; cp++; } /* print the decimal place */ obj->put(obj, '.'); /* print the decimal */ i = ndig - expt; while (i > 0) { obj->put(obj, *cp); i--; cp++; } } }