T power (T a, I n, const T_factory& tfctr) { ARAGELI_ASSERT_0(!is_null(a) || is_positive(n)); bool isneg = is_negative(n); if(isneg) opposite(&n); T res = tfctr.unit(a); while(!is_null(n)) { if(is_odd(n)) res = res * a; a *= a; n >>= 1; } if(isneg) inverse(&res); return res; }

int main() { { const int ia[] = {1, 2, 3, 4, 6, 8, 5, 7}; int r1[10] = {0}; int r2[10] = {0}; typedef std::pair<output_iterator<int*>, int*> P; P p = std::partition_copy(input_iterator<const int*>(std::begin(ia)), input_iterator<const int*>(std::end(ia)), output_iterator<int*>(r1), r2, is_odd()); assert(p.first.base() == r1 + 4); assert(r1[0] == 1); assert(r1[1] == 3); assert(r1[2] == 5); assert(r1[3] == 7); assert(p.second == r2 + 4); assert(r2[0] == 2); assert(r2[1] == 4); assert(r2[2] == 6); assert(r2[3] == 8); } }

static inline AA1 case_2(const AA1 & x, int32_t /*sn*/, const AA1 & n) { typedef typename meta::scalar_of<AA1>::type sAA1; int32_t sk = 1; AA1 t; AA1 pkm2 = One<AA1>(); AA1 qkm2 = x; AA1 pkm1 = One<AA1>(); AA1 qkm1 = x + n; AA1 ans = pkm1/qkm1; do { AA1 test = is_nez(splat<AA1>(is_odd(++sk))); AA1 k_2 = splat<AA1>(sk >> 1); AA1 yk = sel(test, One<AA1>(), x); AA1 xk = seladd(test, k_2, n); AA1 pk = pkm1 * yk + pkm2 * xk; AA1 qk = qkm1 * yk + qkm2 * xk; AA1 r = pk/qk; test = is_nez(qk); t = sel(test,nt2::abs((ans-r)/r),One<AA1>()); ans = sel(test, r, ans); pkm2 = pkm1; pkm1 = pk; qkm2 = qkm1; qkm1 = qk; test = gt(nt2::abs(pk), Expnibig<AA1>()); AA1 fac = sel(test, Halfeps<AA1>(), One<AA1>()); pkm2 *= fac; pkm1 *= fac; qkm2 *= fac; qkm1 *= fac; } while( nt2::bitwise_any(gt(t, Halfeps<AA1>())) ); return ans*nt2::exp(-x); }

int main() { test_iter<forward_iterator<int*> >(); test_iter<bidirectional_iterator<int*> >(); test_iter<random_access_iterator<int*> >(); test_iter<int*>(); test_iter<forward_iterator<int*>, sentinel<int*> >(); test_iter<bidirectional_iterator<int*>, sentinel<int*> >(); test_iter<random_access_iterator<int*>, sentinel<int*> >(); test_range<forward_iterator<int*> >(); test_range<bidirectional_iterator<int*> >(); test_range<random_access_iterator<int*> >(); test_range<int*>(); test_range<forward_iterator<int*>, sentinel<int*> >(); test_range<bidirectional_iterator<int*>, sentinel<int*> >(); test_range<random_access_iterator<int*>, sentinel<int*> >(); // Test projections S ia[] = {S{1}, S{2}, S{3}, S{4}, S{5}, S{6}, S{7}, S{8} ,S{9}}; const unsigned sa = sizeof(ia)/sizeof(ia[0]); S* r = ranges::partition(ia, is_odd(), &S::i); CHECK(r == ia + 5); for (S* i = ia; i < r; ++i) CHECK(is_odd()(i->i)); for (S* i = r; i < ia+sa; ++i) CHECK(!is_odd()(i->i)); // Test rvalue range auto r2 = ranges::partition(ranges::view::all(ia), is_odd(), &S::i); CHECK(r2.get_unsafe() == ia + 5); for (S* i = ia; i < r2.get_unsafe(); ++i) CHECK(is_odd()(i->i)); for (S* i = r2.get_unsafe(); i < ia+sa; ++i) CHECK(!is_odd()(i->i)); return ::test_result(); }

int main(int argc, char *argv[]) { int m, n, g, nhits, mhits; char pocket; while (scanf("%d %d", &m, &n) != EOF) { g = gcd(m, n); nhits = n / g; mhits = m / g; if (!is_odd(nhits) && !is_odd(mhits)) { pocket = 'A'; } else if (is_odd(nhits) && !is_odd(mhits)) { pocket = 'B'; } else if (is_odd(nhits) && is_odd(mhits)) { pocket = 'C'; } else { pocket = 'D'; } printf("%c %d\n", pocket, nhits + mhits - 2); } return 0; }

/* * Note: this does not ones-complement the result since it is used * when computing partial checksums. * For nonSTRUIO_IP mblks, assumes mp->b_rptr+offset is 16 bit aligned. * For STRUIO_IP mblks, assumes mp->b_datap->db_struiobase is 16 bit aligned. * * Note: for STRUIO_IP special mblks some data may have been previously * checksumed, this routine will handle additional data prefixed within * an mblk or b_cont (chained) mblk(s). This routine will also handle * suffixed b_cont mblk(s) and data suffixed within an mblk. */ unsigned int ip_cksum(mblk_t *mp, int offset, uint_t sum) { ushort_t *w; ssize_t mlen; int pmlen; mblk_t *pmp; dblk_t *dp = mp->b_datap; ushort_t psum = 0; #ifdef ZC_TEST if (noswcksum) return (0xffff); #endif ASSERT(dp); if (mp->b_cont == NULL) { /* * May be fast-path, only one mblk. */ w = (ushort_t *)(mp->b_rptr + offset); if (dp->db_struioflag & STRUIO_IP) { /* * Checksum any data not already done by * the caller and add in any partial checksum. */ if ((offset > dp->db_cksumstart) || mp->b_wptr != (uchar_t *)(mp->b_rptr + dp->db_cksumend)) { /* * Mblk data pointers aren't inclusive * of uio data, so disregard checksum. * * not using all of data in dblk make sure * not use to use the precalculated checksum * in this case. */ dp->db_struioflag &= ~STRUIO_IP; goto norm; } ASSERT(mp->b_wptr == (mp->b_rptr + dp->db_cksumend)); psum = *(ushort_t *)dp->db_struioun.data; if ((mlen = dp->db_cksumstart - offset) < 0) mlen = 0; if (is_odd(mlen)) goto slow; if (mlen && dp->db_cksumstart != dp->db_cksumstuff && dp->db_cksumend != dp->db_cksumstuff) { /* * There is prefix data to do and some uio * data has already been checksumed and there * is more uio data to do, so do the prefix * data first, then do the remainder of the * uio data. */ sum = ip_ocsum(w, mlen >> 1, sum); w = (ushort_t *)(mp->b_rptr + dp->db_cksumstuff); if (is_odd(w)) { pmp = mp; goto slow1; } mlen = dp->db_cksumend - dp->db_cksumstuff; } else if (dp->db_cksumend != dp->db_cksumstuff) {

surface getMinimap(int w, int h, const gamemap &map, const team *vw) { const int scale = 8; DBG_DP << "creating minimap " << int(map.w()*scale*0.75) << "," << map.h()*scale << "\n"; const size_t map_width = map.w()*scale*3/4; const size_t map_height = map.h()*scale; if(map_width == 0 || map_height == 0) { return surface(NULL); } surface minimap(create_neutral_surface(map_width, map_height)); if(minimap == NULL) return surface(NULL); typedef mini_terrain_cache_map cache_map; cache_map *normal_cache = &mini_terrain_cache; cache_map *fog_cache = &mini_fogged_terrain_cache; for(int y = 0; y != map.total_height(); ++y) { for(int x = 0; x != map.total_width(); ++x) { surface surf(NULL); const map_location loc(x,y); if(map.on_board(loc)) { const bool shrouded = (vw != NULL && vw->shrouded(loc)); // shrouded hex are not considered fogged (no need to fog a black image) const bool fogged = (vw != NULL && !shrouded && vw->fogged(loc)); const t_translation::t_terrain terrain = shrouded ? t_translation::VOID_TERRAIN : map[loc]; const terrain_type& terrain_info = map.get_terrain_info(terrain); bool need_fogging = false; cache_map* cache = fogged ? fog_cache : normal_cache; cache_map::iterator i = cache->find(terrain); if (fogged && i == cache->end()) { // we don't have the fogged version in cache // try the normal cache and ask fogging the image cache = normal_cache; i = cache->find(terrain); need_fogging = true; } if(i == cache->end()) { std::string base_file = "terrain/" + terrain_info.minimap_image() + ".png"; surface tile = get_image(base_file,image::HEXED); //Compose images of base and overlay if necessary // NOTE we also skip overlay when base is missing (to avoid hiding the error) if(tile != NULL && map.get_terrain_info(terrain).is_combined()) { std::string overlay_file = "terrain/" + terrain_info.minimap_image_overlay() + ".png"; surface overlay = get_image(overlay_file,image::HEXED); if(overlay != NULL && overlay != tile) { surface combined = create_neutral_surface(tile->w, tile->h); SDL_Rect r = create_rect(0,0,0,0); sdl_blit(tile, NULL, combined, &r); r.x = std::max(0, (tile->w - overlay->w)/2); r.y = std::max(0, (tile->h - overlay->h)/2); //blit_surface needs neutral surface surface overlay_neutral = make_neutral_surface(overlay); blit_surface(overlay_neutral, NULL, combined, &r); tile = combined; } } surf = scale_surface_sharp(tile, scale, scale); i = normal_cache->insert(cache_map::value_type(terrain,surf)).first; } surf = i->second; if (need_fogging) { surf = adjust_surface_color(surf,-50,-50,-50); fog_cache->insert(cache_map::value_type(terrain,surf)); } // we need a balanced shift up and down of the hexes. // if not, only the bottom half-hexes are clipped // and it looks asymmetrical. // also do 1-pixel shift because the scaling // function seems to do it with its rounding SDL_Rect maprect = create_rect( x * scale * 3 / 4 - 1 , y * scale + scale / 4 * (is_odd(x) ? 1 : -1) - 1 , 0 , 0); if(surf != NULL) sdl_blit(surf, NULL, minimap, &maprect); } } } double wratio = w*1.0 / minimap->w; double hratio = h*1.0 / minimap->h; double ratio = std::min<double>(wratio, hratio); minimap = scale_surface_sharp(minimap, static_cast<int>(minimap->w * ratio), static_cast<int>(minimap->h * ratio)); DBG_DP << "done generating minimap\n"; return minimap; }

/* The computation of z = pow(x,y) is done by z = exp(y * log(x)) = x^y For the special cases, see Section F.9.4.4 of the C standard: _ pow(±0, y) = ±inf for y an odd integer < 0. _ pow(±0, y) = +inf for y < 0 and not an odd integer. _ pow(±0, y) = ±0 for y an odd integer > 0. _ pow(±0, y) = +0 for y > 0 and not an odd integer. _ pow(-1, ±inf) = 1. _ pow(+1, y) = 1 for any y, even a NaN. _ pow(x, ±0) = 1 for any x, even a NaN. _ pow(x, y) = NaN for finite x < 0 and finite non-integer y. _ pow(x, -inf) = +inf for |x| < 1. _ pow(x, -inf) = +0 for |x| > 1. _ pow(x, +inf) = +0 for |x| < 1. _ pow(x, +inf) = +inf for |x| > 1. _ pow(-inf, y) = -0 for y an odd integer < 0. _ pow(-inf, y) = +0 for y < 0 and not an odd integer. _ pow(-inf, y) = -inf for y an odd integer > 0. _ pow(-inf, y) = +inf for y > 0 and not an odd integer. _ pow(+inf, y) = +0 for y < 0. _ pow(+inf, y) = +inf for y > 0. */ int mpfr_pow (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode) { int inexact; int cmp_x_1; int y_is_integer; MPFR_SAVE_EXPO_DECL (expo); MPFR_LOG_FUNC (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, mpfr_get_prec (y), mpfr_log_prec, y, rnd_mode), ("z[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (z), mpfr_log_prec, z, inexact)); if (MPFR_ARE_SINGULAR (x, y)) { /* pow(x, 0) returns 1 for any x, even a NaN. */ if (MPFR_UNLIKELY (MPFR_IS_ZERO (y))) return mpfr_set_ui (z, 1, rnd_mode); else if (MPFR_IS_NAN (x)) { MPFR_SET_NAN (z); MPFR_RET_NAN; } else if (MPFR_IS_NAN (y)) { /* pow(+1, NaN) returns 1. */ if (mpfr_cmp_ui (x, 1) == 0) return mpfr_set_ui (z, 1, rnd_mode); MPFR_SET_NAN (z); MPFR_RET_NAN; } else if (MPFR_IS_INF (y)) { if (MPFR_IS_INF (x)) { if (MPFR_IS_POS (y)) MPFR_SET_INF (z); else MPFR_SET_ZERO (z); MPFR_SET_POS (z); MPFR_RET (0); } else { int cmp; cmp = mpfr_cmpabs (x, __gmpfr_one) * MPFR_INT_SIGN (y); MPFR_SET_POS (z); if (cmp > 0) { /* Return +inf. */ MPFR_SET_INF (z); MPFR_RET (0); } else if (cmp < 0) { /* Return +0. */ MPFR_SET_ZERO (z); MPFR_RET (0); } else { /* Return 1. */ return mpfr_set_ui (z, 1, rnd_mode); } } } else if (MPFR_IS_INF (x)) { int negative; /* Determine the sign now, in case y and z are the same object */ negative = MPFR_IS_NEG (x) && is_odd (y); if (MPFR_IS_POS (y)) MPFR_SET_INF (z); else MPFR_SET_ZERO (z); if (negative) MPFR_SET_NEG (z); else MPFR_SET_POS (z); MPFR_RET (0); } else { int negative; MPFR_ASSERTD (MPFR_IS_ZERO (x)); /* Determine the sign now, in case y and z are the same object */ negative = MPFR_IS_NEG(x) && is_odd (y); if (MPFR_IS_NEG (y)) { MPFR_ASSERTD (! MPFR_IS_INF (y)); MPFR_SET_INF (z); mpfr_set_divby0 (); } else MPFR_SET_ZERO (z); if (negative) MPFR_SET_NEG (z); else MPFR_SET_POS (z); MPFR_RET (0); } } /* x^y for x < 0 and y not an integer is not defined */ y_is_integer = mpfr_integer_p (y); if (MPFR_IS_NEG (x) && ! y_is_integer) { MPFR_SET_NAN (z); MPFR_RET_NAN; } /* now the result cannot be NaN: (1) either x > 0 (2) or x < 0 and y is an integer */ cmp_x_1 = mpfr_cmpabs (x, __gmpfr_one); if (cmp_x_1 == 0) return mpfr_set_si (z, MPFR_IS_NEG (x) && is_odd (y) ? -1 : 1, rnd_mode); /* now we have: (1) either x > 0 (2) or x < 0 and y is an integer and in addition |x| <> 1. */ /* detect overflow: an overflow is possible if (a) |x| > 1 and y > 0 (b) |x| < 1 and y < 0. FIXME: this assumes 1 is always representable. FIXME2: maybe we can test overflow and underflow simultaneously. The idea is the following: first compute an approximation to y * log2|x|, using rounding to nearest. If |x| is not too near from 1, this approximation should be accurate enough, and in most cases enable one to prove that there is no underflow nor overflow. Otherwise, it should enable one to check only underflow or overflow, instead of both cases as in the present case. */ if (cmp_x_1 * MPFR_SIGN (y) > 0) { mpfr_t t; int negative, overflow; MPFR_SAVE_EXPO_MARK (expo); mpfr_init2 (t, 53); /* we want a lower bound on y*log2|x|: (i) if x > 0, it suffices to round log2(x) toward zero, and to round y*o(log2(x)) toward zero too; (ii) if x < 0, we first compute t = o(-x), with rounding toward 1, and then follow as in case (1). */ if (MPFR_SIGN (x) > 0) mpfr_log2 (t, x, MPFR_RNDZ); else { mpfr_neg (t, x, (cmp_x_1 > 0) ? MPFR_RNDZ : MPFR_RNDU); mpfr_log2 (t, t, MPFR_RNDZ); } mpfr_mul (t, t, y, MPFR_RNDZ); overflow = mpfr_cmp_si (t, __gmpfr_emax) > 0; mpfr_clear (t); MPFR_SAVE_EXPO_FREE (expo); if (overflow) { MPFR_LOG_MSG (("early overflow detection\n", 0)); negative = MPFR_SIGN(x) < 0 && is_odd (y); return mpfr_overflow (z, rnd_mode, negative ? -1 : 1); } } /* Basic underflow checking. One has: * - if y > 0, |x^y| < 2^(EXP(x) * y); * - if y < 0, |x^y| <= 2^((EXP(x) - 1) * y); * so that one can compute a value ebound such that |x^y| < 2^ebound. * If we have ebound <= emin - 2 (emin - 1 in directed rounding modes), * then there is an underflow and we can decide the return value. */ if (MPFR_IS_NEG (y) ? (MPFR_GET_EXP (x) > 1) : (MPFR_GET_EXP (x) < 0)) { mpfr_t tmp; mpfr_eexp_t ebound; int inex2; /* We must restore the flags. */ MPFR_SAVE_EXPO_MARK (expo); mpfr_init2 (tmp, sizeof (mpfr_exp_t) * CHAR_BIT); inex2 = mpfr_set_exp_t (tmp, MPFR_GET_EXP (x), MPFR_RNDN); MPFR_ASSERTN (inex2 == 0); if (MPFR_IS_NEG (y)) { inex2 = mpfr_sub_ui (tmp, tmp, 1, MPFR_RNDN); MPFR_ASSERTN (inex2 == 0); } mpfr_mul (tmp, tmp, y, MPFR_RNDU); if (MPFR_IS_NEG (y)) mpfr_nextabove (tmp); /* tmp doesn't necessarily fit in ebound, but that doesn't matter since we get the minimum value in such a case. */ ebound = mpfr_get_exp_t (tmp, MPFR_RNDU); mpfr_clear (tmp); MPFR_SAVE_EXPO_FREE (expo); if (MPFR_UNLIKELY (ebound <= __gmpfr_emin - (rnd_mode == MPFR_RNDN ? 2 : 1))) { /* warning: mpfr_underflow rounds away from 0 for MPFR_RNDN */ MPFR_LOG_MSG (("early underflow detection\n", 0)); return mpfr_underflow (z, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode, MPFR_SIGN (x) < 0 && is_odd (y) ? -1 : 1); } } /* If y is an integer, we can use mpfr_pow_z (based on multiplications), but if y is very large (I'm not sure about the best threshold -- VL), we shouldn't use it, as it can be very slow and take a lot of memory (and even crash or make other programs crash, as several hundred of MBs may be necessary). Note that in such a case, either x = +/-2^b (this case is handled below) or x^y cannot be represented exactly in any precision supported by MPFR (the general case uses this property). */ if (y_is_integer && (MPFR_GET_EXP (y) <= 256)) { mpz_t zi; MPFR_LOG_MSG (("special code for y not too large integer\n", 0)); mpz_init (zi); mpfr_get_z (zi, y, MPFR_RNDN); inexact = mpfr_pow_z (z, x, zi, rnd_mode); mpz_clear (zi); return inexact; } /* Special case (+/-2^b)^Y which could be exact. If x is negative, then necessarily y is a large integer. */ { mpfr_exp_t b = MPFR_GET_EXP (x) - 1; MPFR_ASSERTN (b >= LONG_MIN && b <= LONG_MAX); /* FIXME... */ if (mpfr_cmp_si_2exp (x, MPFR_SIGN(x), b) == 0) { mpfr_t tmp; int sgnx = MPFR_SIGN (x); MPFR_LOG_MSG (("special case (+/-2^b)^Y\n", 0)); /* now x = +/-2^b, so x^y = (+/-1)^y*2^(b*y) is exact whenever b*y is an integer */ MPFR_SAVE_EXPO_MARK (expo); mpfr_init2 (tmp, MPFR_PREC (y) + sizeof (long) * CHAR_BIT); inexact = mpfr_mul_si (tmp, y, b, MPFR_RNDN); /* exact */ MPFR_ASSERTN (inexact == 0); /* Note: as the exponent range has been extended, an overflow is not possible (due to basic overflow and underflow checking above, as the result is ~ 2^tmp), and an underflow is not possible either because b is an integer (thus either 0 or >= 1). */ MPFR_CLEAR_FLAGS (); inexact = mpfr_exp2 (z, tmp, rnd_mode); mpfr_clear (tmp); if (sgnx < 0 && is_odd (y)) { mpfr_neg (z, z, rnd_mode); inexact = -inexact; } /* Without the following, the overflows3 test in tpow.c fails. */ MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (z, inexact, rnd_mode); } } MPFR_SAVE_EXPO_MARK (expo); /* Case where |y * log(x)| is very small. Warning: x can be negative, in that case y is a large integer. */ { mpfr_t t; mpfr_exp_t err; /* We need an upper bound on the exponent of y * log(x). */ mpfr_init2 (t, 16); if (MPFR_IS_POS(x)) mpfr_log (t, x, cmp_x_1 < 0 ? MPFR_RNDD : MPFR_RNDU); /* away from 0 */ else { /* if x < -1, round to +Inf, else round to zero */ mpfr_neg (t, x, (mpfr_cmp_si (x, -1) < 0) ? MPFR_RNDU : MPFR_RNDD); mpfr_log (t, t, (mpfr_cmp_ui (t, 1) < 0) ? MPFR_RNDD : MPFR_RNDU); } MPFR_ASSERTN (MPFR_IS_PURE_FP (t)); err = MPFR_GET_EXP (y) + MPFR_GET_EXP (t); mpfr_clear (t); MPFR_CLEAR_FLAGS (); MPFR_SMALL_INPUT_AFTER_SAVE_EXPO (z, __gmpfr_one, - err, 0, (MPFR_SIGN (y) > 0) ^ (cmp_x_1 < 0), rnd_mode, expo, {}); } /* General case */ inexact = mpfr_pow_general (z, x, y, rnd_mode, y_is_integer, &expo); MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (z, inexact, rnd_mode); }

int print_properties_num(longnum num) { printf("%llu:\nprime factors: ", num); print_prime_factors(num); printf("\n"); if ( is_abundant(num) ) printf(" abundant"); if ( is_amicable(num) ) printf(" amicable"); if ( is_apocalyptic_power(num) ) printf(" apocalyptic_power"); if ( is_aspiring(num) ) printf(" aspiring"); if ( is_automorphic(num) ) printf(" automorphic"); if ( is_cake(num) ) printf(" cake"); if ( is_carmichael(num) ) printf(" carmichael"); if ( is_catalan(num) ) printf(" catalan"); if ( is_composite(num) ) printf(" composite"); if ( is_compositorial(num) ) printf(" compositorial"); if ( is_cube(num) ) printf(" cube"); if ( is_deficient(num) ) printf(" deficient"); if ( is_easy_to_remember(num) ) printf(" easy_to_remember"); if ( is_ecci1(num) ) printf(" ecci1"); if ( is_ecci2(num) ) printf(" ecci2"); if ( is_even(num) ) printf(" even"); if ( is_evil(num) ) printf(" evil"); if ( is_factorial(num) ) printf(" factorial"); if ( is_fermat(num) ) printf(" fermat"); if ( is_fibonacci(num) ) printf(" fibonacci"); if ( is_google(num) ) printf(" google"); if ( is_happy(num) ) printf(" happy"); if ( is_hungry(num) ) printf(" hungry"); if ( is_hypotenuse(num) ) printf(" hypotenuse"); if ( is_lazy_caterer(num) ) printf(" lazy_caterer"); if ( is_lucky(num) ) printf(" lucky"); if ( is_mersenne_prime(num) ) printf(" mersenne_prime"); if ( is_mersenne(num) ) printf(" mersenne"); if ( is_narcissistic(num) ) printf(" narcissistic"); if ( is_odd(num) ) printf(" odd"); if ( is_odious(num) ) printf(" odious"); if ( is_palindrome(num) ) printf(" palindrome"); if ( is_palindromic_prime(num) ) printf(" palindromic_prime"); if ( is_parasite(num) ) printf(" parasite"); if ( is_pentagonal(num) ) printf(" pentagonal"); if ( is_perfect(num) ) printf(" perfect"); if ( is_persistent(num) ) printf(" persistent"); if ( is_power_of_2(num) ) printf(" power_of_2"); if ( is_powerful(num) ) printf(" powerful"); if ( is_practical(num) ) printf(" practical"); if ( is_prime(num) ) printf(" prime"); if ( is_primorial(num) ) printf(" primorial"); if ( is_product_perfect(num) ) printf(" product_perfect"); if ( is_pronic(num) ) printf(" pronic"); if ( is_repdigit(num) ) printf(" repdigit"); if ( is_repunit(num) ) printf(" repunit"); if ( is_smith(num) ) printf(" smith"); if ( is_sociable(num) ) printf(" sociable"); if ( is_square_free(num) ) printf(" square_free"); if ( is_square(num) ) printf(" square"); if ( is_tetrahedral(num) ) printf(" tetrahedral"); if ( is_triangular(num) ) printf(" triangular"); if ( is_twin(num) ) printf(" twin"); if ( is_ulam(num) ) printf(" ulam"); if ( is_undulating(num) ) printf(" undulating"); if ( is_untouchable(num) ) printf(" untouchable"); if ( is_vampire(num) ) printf(" vampire"); if ( is_weird(num) ) printf(" weird"); printf("\n\n"); return 0; }

std::string default_map_generator::generate_map(std::map<map_location,std::string>* labels) { // Suppress labels? if ( !show_labels_ ) labels = NULL; // the random generator thinks odd widths are nasty, so make them even if (is_odd(width_)) ++width_; size_t iterations = (iterations_*width_*height_)/(default_width_*default_height_); size_t island_size = 0; size_t island_off_center = 0; size_t max_lakes = max_lakes_; if(island_size_ >= max_coastal) { //islands look good with much fewer iterations than normal, and fewer lake iterations /= 10; max_lakes /= 9; //the radius of the island should be up to half the width of the map const size_t island_radius = 50 + ((max_island - island_size_)*50)/(max_island - max_coastal); island_size = (island_radius*(width_/2))/100; } else if(island_size_ > 0) { DBG_NG << "coastal...\n"; //the radius of the island should be up to twice the width of the map const size_t island_radius = 40 + ((max_coastal - island_size_)*40)/max_coastal; island_size = (island_radius*width_*2)/100; island_off_center = std::min<size_t>(width_,height_); DBG_NG << "calculated coastal params...\n"; } // A map generator can fail so try a few times to get a map before aborting. std::string map; // Keep a copy of labels as it can be written to by the map generator func std::map<map_location,std::string> labels_copy; std::map<map_location,std::string> * labels_ptr = labels ? &labels_copy : NULL; std::string error_message; int tries = 10; do { if (labels) { // Reset the labels. labels_copy = *labels; } try{ map = default_generate_map(width_, height_, island_size, island_off_center, iterations, hill_size_, max_lakes, (nvillages_ * width_ * height_) / 1000, castle_size_, nplayers_, link_castles_, labels_ptr, cfg_); error_message = ""; } catch (mapgen_exception& exc){ error_message = exc.message; } --tries; } while (tries && map.empty()); if (labels) { labels->swap(labels_copy); } if (error_message != "") throw mapgen_exception(error_message); return map; }

/** * Clears shroud from a single location. * This also records sighted events for later firing. * * In a few cases, this will also clear corner hexes that otherwise would * not normally get cleared. * @param tm The team whose fog/shroud is affected. * @param loc The location to clear. * @param view_loc The location viewer is assumed at (for sighted events). * @param event_non_loc The unit at this location cannot be sighted * (used to prevent a unit from sighting itself). * @param viewer_id The underlying ID of the unit doing the sighting (for events). * @param check_units If false, there is no checking for an uncovered unit. * @param enemy_count Incremented if an enemy is uncovered. * @param friend_count Incremented if a friend is uncovered. * @param spectator Will be told if a unit is uncovered. * * @return whether or not information was uncovered (i.e. returns true if * the specified location was fogged/ shrouded under shared vision/maps). */ bool shroud_clearer::clear_loc(team &tm, const map_location &loc, const map_location &view_loc, const map_location &event_non_loc, std::size_t viewer_id, bool check_units, std::size_t &enemy_count, std::size_t &friend_count, move_unit_spectator * spectator) { const gamemap &map = resources::gameboard->map(); // This counts as clearing a tile for the return value if it is on the // board and currently fogged under shared vision. (No need to explicitly // check for shrouded since shrouded implies fogged.) bool was_fogged = tm.fogged(loc); bool result = was_fogged && map.on_board(loc); // Clear the border as well as the board, so that the half-hexes // at the edge can also be cleared of fog/shroud. if ( map.on_board_with_border(loc) ) { // Both functions should be executed so don't use || which // uses short-cut evaluation. // (This is different than the return value because shared vision does // not apply here.) if ( tm.clear_shroud(loc) | tm.clear_fog(loc) ) { // If we are near a corner, the corner might also need to be cleared. // This happens at the lower-left corner and at either the upper- or // lower- right corner (depending on the width). // Lower-left corner: if ( loc.x == 0 && loc.y == map.h()-1 ) { const map_location corner(-1, map.h()); tm.clear_shroud(corner); tm.clear_fog(corner); } // Lower-right corner, odd width: else if ( is_odd(map.w()) && loc.x == map.w()-1 && loc.y == map.h()-1 ) { const map_location corner(map.w(), map.h()); tm.clear_shroud(corner); tm.clear_fog(corner); } // Upper-right corner, even width: else if ( is_even(map.w()) && loc.x == map.w()-1 && loc.y == 0) { const map_location corner(map.w(), -1); tm.clear_shroud(corner); tm.clear_fog(corner); } } } // Possible screen invalidation. if ( was_fogged ) { display::get_singleton()->invalidate(loc); // Need to also invalidate adjacent hexes to get rid of the // "fog edge" graphics. adjacent_loc_array_t adjacent; get_adjacent_tiles(loc, adjacent.data()); for (unsigned i = 0; i < adjacent.size(); ++i ) display::get_singleton()->invalidate(adjacent[i]); } // Check for units? if ( result && check_units && loc != event_non_loc ) { // Uncovered a unit? unit_map::const_iterator sight_it = resources::gameboard->find_visible_unit(loc, tm); if ( sight_it.valid() ) { record_sighting(*sight_it, loc, viewer_id, view_loc); // Track this? if ( !sight_it->get_state(unit::STATE_PETRIFIED) ) { if ( tm.is_enemy(sight_it->side()) ) { ++enemy_count; if ( spectator ) spectator->add_seen_enemy(sight_it); } else { ++friend_count; if ( spectator ) spectator->add_seen_friend(sight_it); } } } } return result; }

int main(void) { int square[9]; int v[9]; int head=0, i=0, j=0; v[0] = 0; v[1] = 1; v[2] = 2; v[3] = 7; v[4] = 8; v[5] = 3; v[6] = 6; v[7] = 5; v[8] = 4; //input printf("input 9 numbers\n"); for (i=0; i < 9; i++) { scanf("%d", &square[v[i]]); } output(square, v); if (square[0] != 0) { head = 0; i = 0; while ((square[head+i] != 0) && i<8) i++; if (i == 8) { printf("Input Error\n"); return 0; } else if (is_odd(head+i)) { square[head+i] = square[8]; } else { square[head+i] = square[head+i+1]; square[head+i] = square[8]; } i = 0; while ((square[i] != 1) && i<8) i++; if (i == 8) { printf("abc\n"); } else { head = i; for (i=1; i<8; i++) for (j=i-1; j>-1; j--) if (square[(head+j+1)%8] < square[(head+j)%8]) exchange(square, v, &head, j); } } return 0; }

static void tst (void) { int sv = sizeof (val) / sizeof (*val); int i, j; int rnd; mpfr_t x, y, z, tmp; mpfr_inits2 (53, x, y, z, tmp, (mpfr_ptr) 0); for (i = 0; i < sv; i++) for (j = 0; j < sv; j++) RND_LOOP (rnd) { int exact, inex; unsigned int flags; if (my_setstr (x, val[i]) || my_setstr (y, val[j])) { printf ("internal error for (%d,%d,%d)\n", i, j, rnd); exit (1); } mpfr_clear_flags (); inex = mpfr_pow (z, x, y, (mpfr_rnd_t) rnd); flags = __gmpfr_flags; if (! MPFR_IS_NAN (z) && mpfr_nanflag_p ()) err ("got NaN flag without NaN value", i, j, rnd, z, inex); if (MPFR_IS_NAN (z) && ! mpfr_nanflag_p ()) err ("got NaN value without NaN flag", i, j, rnd, z, inex); if (inex != 0 && ! mpfr_inexflag_p ()) err ("got non-zero ternary value without inexact flag", i, j, rnd, z, inex); if (inex == 0 && mpfr_inexflag_p ()) err ("got null ternary value with inexact flag", i, j, rnd, z, inex); if (i >= 3 && j >= 3) { if (mpfr_underflow_p ()) err ("got underflow", i, j, rnd, z, inex); if (mpfr_overflow_p ()) err ("got overflow", i, j, rnd, z, inex); exact = MPFR_IS_SINGULAR (z) || (mpfr_mul_2ui (tmp, z, 16, MPFR_RNDN), mpfr_integer_p (tmp)); if (exact && inex != 0) err ("got exact value with ternary flag different from 0", i, j, rnd, z, inex); if (! exact && inex == 0) err ("got inexact value with ternary flag equal to 0", i, j, rnd, z, inex); } if (MPFR_IS_ZERO (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y)) { if (MPFR_IS_NEG (y) && ! MPFR_IS_INF (z)) err ("expected an infinity", i, j, rnd, z, inex); if (MPFR_IS_POS (y) && ! MPFR_IS_ZERO (z)) err ("expected a zero", i, j, rnd, z, inex); if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z)) err ("wrong sign", i, j, rnd, z, inex); } if (! MPFR_IS_NAN (x) && mpfr_cmp_si (x, -1) == 0) { /* x = -1 */ if (! (MPFR_IS_INF (y) || mpfr_integer_p (y)) && ! MPFR_IS_NAN (z)) err ("expected NaN", i, j, rnd, z, inex); if ((MPFR_IS_INF (y) || (mpfr_integer_p (y) && ! is_odd (y))) && ! mpfr_equal_p (z, __gmpfr_one)) err ("expected 1", i, j, rnd, z, inex); if (is_odd (y) && (MPFR_IS_NAN (z) || mpfr_cmp_si (z, -1) != 0)) err ("expected -1", i, j, rnd, z, inex); } if ((mpfr_equal_p (x, __gmpfr_one) || MPFR_IS_ZERO (y)) && ! mpfr_equal_p (z, __gmpfr_one)) err ("expected 1", i, j, rnd, z, inex); if (MPFR_IS_PURE_FP (x) && MPFR_IS_NEG (x) && MPFR_IS_FP (y) && ! mpfr_integer_p (y) && ! MPFR_IS_NAN (z)) err ("expected NaN", i, j, rnd, z, inex); if (MPFR_IS_INF (y) && MPFR_NOTZERO (x)) { int cmpabs1 = mpfr_cmpabs (x, __gmpfr_one); if ((MPFR_IS_NEG (y) ? (cmpabs1 < 0) : (cmpabs1 > 0)) && ! (MPFR_IS_POS (z) && MPFR_IS_INF (z))) err ("expected +Inf", i, j, rnd, z, inex); if ((MPFR_IS_NEG (y) ? (cmpabs1 > 0) : (cmpabs1 < 0)) && ! (MPFR_IS_POS (z) && MPFR_IS_ZERO (z))) err ("expected +0", i, j, rnd, z, inex); } if (MPFR_IS_INF (x) && ! MPFR_IS_NAN (y) && MPFR_NOTZERO (y)) { if (MPFR_IS_POS (y) && ! MPFR_IS_INF (z)) err ("expected an infinity", i, j, rnd, z, inex); if (MPFR_IS_NEG (y) && ! MPFR_IS_ZERO (z)) err ("expected a zero", i, j, rnd, z, inex); if ((MPFR_IS_NEG (x) && is_odd (y)) ^ MPFR_IS_NEG (z)) err ("wrong sign", i, j, rnd, z, inex); } test_others (val[i], val[j], (mpfr_rnd_t) rnd, x, y, z, inex, flags, "tst"); } mpfr_clears (x, y, z, tmp, (mpfr_ptr) 0); }

bool is_even(int n) { if(!n) return true; else is_odd(n-1); }

void test_range() { // check mixed int ia[] = {1, 2, 3, 4, 5, 6, 7, 8 ,9}; const unsigned sa = sizeof(ia)/sizeof(ia[0]); Iter r = ranges::partition(::as_lvalue(ranges::make_iterator_range(Iter(ia), Sent(ia + sa))), is_odd()); CHECK(base(r) == ia + 5); for (int* i = ia; i < base(r); ++i) CHECK(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) CHECK(!is_odd()(*i)); // check empty r = ranges::partition(::as_lvalue(ranges::make_iterator_range(Iter(ia), Sent(ia))), is_odd()); CHECK(base(r) == ia); // check all false for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i; r = ranges::partition(::as_lvalue(ranges::make_iterator_range(Iter(ia), Sent(ia+sa))), is_odd()); CHECK(base(r) == ia); // check all true for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i+1; r = ranges::partition(::as_lvalue(ranges::make_iterator_range(Iter(ia), Sent(ia+sa))), is_odd()); CHECK(base(r) == ia+sa); // check all true but last for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i+1; ia[sa-1] = 10; r = ranges::partition(::as_lvalue(ranges::make_iterator_range(Iter(ia), Sent(ia+sa))), is_odd()); CHECK(base(r) == ia+sa-1); for (int* i = ia; i < base(r); ++i) CHECK(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) CHECK(!is_odd()(*i)); // check all true but first for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i+1; ia[0] = 10; r = ranges::partition(::as_lvalue(ranges::make_iterator_range(Iter(ia), Sent(ia+sa))), is_odd()); CHECK(base(r) == ia+sa-1); for (int* i = ia; i < base(r); ++i) CHECK(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) CHECK(!is_odd()(*i)); // check all false but last for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i; ia[sa-1] = 11; r = ranges::partition(::as_lvalue(ranges::make_iterator_range(Iter(ia), Sent(ia+sa))), is_odd()); CHECK(base(r) == ia+1); for (int* i = ia; i < base(r); ++i) CHECK(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) CHECK(!is_odd()(*i)); // check all false but first for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i; ia[0] = 11; r = ranges::partition(::as_lvalue(ranges::make_iterator_range(Iter(ia), Sent(ia+sa))), is_odd()); CHECK(base(r) == ia+1); for (int* i = ia; i < base(r); ++i) CHECK(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) CHECK(!is_odd()(*i)); }

bool is_even() const { return !is_odd(); }

/* Put in z the value of x^y, rounded according to 'rnd'. Return the inexact flag in [0, 10]. */ int mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) { int ret = -2, loop, x_real, y_real, z_real = 0, z_imag = 0; mpc_t t, u; mp_prec_t p, q, pr, pi, maxprec; long Q; x_real = mpfr_zero_p (MPC_IM(x)); y_real = mpfr_zero_p (MPC_IM(y)); if (y_real && mpfr_zero_p (MPC_RE(y))) /* case y zero */ { if (x_real && mpfr_zero_p (MPC_RE(x))) /* 0^0 = NaN +i*NaN */ { mpfr_set_nan (MPC_RE(z)); mpfr_set_nan (MPC_IM(z)); return 0; } else /* x^0 = 1 +/- i*0 even for x=NaN see algorithms.tex for the sign of zero */ { mpfr_t n; int inex, cx1; int sign_zi; /* cx1 < 0 if |x| < 1 cx1 = 0 if |x| = 1 cx1 > 0 if |x| > 1 */ mpfr_init (n); inex = mpc_norm (n, x, GMP_RNDN); cx1 = mpfr_cmp_ui (n, 1); if (cx1 == 0 && inex != 0) cx1 = -inex; sign_zi = (cx1 < 0 && mpfr_signbit (MPC_IM (y)) == 0) || (cx1 == 0 && mpfr_signbit (MPC_IM (x)) != mpfr_signbit (MPC_RE (y))) || (cx1 > 0 && mpfr_signbit (MPC_IM (y))); /* warning: mpc_set_ui_ui does not set Im(z) to -0 if Im(rnd)=RNDD */ ret = mpc_set_ui_ui (z, 1, 0, rnd); if (MPC_RND_IM (rnd) == GMP_RNDD || sign_zi) mpc_conj (z, z, MPC_RNDNN); mpfr_clear (n); return ret; } } if (mpfr_nan_p (MPC_RE(x)) || mpfr_nan_p (MPC_IM(x)) || mpfr_nan_p (MPC_RE(y)) || mpfr_nan_p (MPC_IM(y)) || mpfr_inf_p (MPC_RE(x)) || mpfr_inf_p (MPC_IM(x)) || mpfr_inf_p (MPC_RE(y)) || mpfr_inf_p (MPC_IM(y))) { /* special values: exp(y*log(x)) */ mpc_init2 (u, 2); mpc_log (u, x, MPC_RNDNN); mpc_mul (u, u, y, MPC_RNDNN); ret = mpc_exp (z, u, rnd); mpc_clear (u); goto end; } if (x_real) /* case x real */ { if (mpfr_zero_p (MPC_RE(x))) /* x is zero */ { /* special values: exp(y*log(x)) */ mpc_init2 (u, 2); mpc_log (u, x, MPC_RNDNN); mpc_mul (u, u, y, MPC_RNDNN); ret = mpc_exp (z, u, rnd); mpc_clear (u); goto end; } /* Special case 1^y = 1 */ if (mpfr_cmp_ui (MPC_RE(x), 1) == 0) { int s1, s2; s1 = mpfr_signbit (MPC_RE (y)); s2 = mpfr_signbit (MPC_IM (x)); ret = mpc_set_ui (z, +1, rnd); /* the sign of the zero imaginary part is known in some cases (see algorithm.tex). In such cases we have (x +s*0i)^(y+/-0i) = x^y + s*sign(y)*0i where s = +/-1. We extend here this rule to fix the sign of the zero part. Note that the sign must also be set explicitly when rnd=RNDD because mpfr_set_ui(z_i, 0, rnd) always sets z_i to +0. */ if (MPC_RND_IM (rnd) == GMP_RNDD || s1 != s2) mpc_conj (z, z, MPC_RNDNN); goto end; } /* x^y is real when: (a) x is real and y is integer (b) x is real non-negative and y is real */ if (y_real && (mpfr_integer_p (MPC_RE(y)) || mpfr_cmp_ui (MPC_RE(x), 0) >= 0)) { int s1, s2; s1 = mpfr_signbit (MPC_RE (y)); s2 = mpfr_signbit (MPC_IM (x)); ret = mpfr_pow (MPC_RE(z), MPC_RE(x), MPC_RE(y), MPC_RND_RE(rnd)); ret = MPC_INEX(ret, mpfr_set_ui (MPC_IM(z), 0, MPC_RND_IM(rnd))); /* the sign of the zero imaginary part is known in some cases (see algorithm.tex). In such cases we have (x +s*0i)^(y+/-0i) = x^y + s*sign(y)*0i where s = +/-1. We extend here this rule to fix the sign of the zero part. Note that the sign must also be set explicitly when rnd=RNDD because mpfr_set_ui(z_i, 0, rnd) always sets z_i to +0. */ if (MPC_RND_IM(rnd) == GMP_RNDD || s1 != s2) mpfr_neg (MPC_IM(z), MPC_IM(z), MPC_RND_IM(rnd)); goto end; } /* (-1)^(n+I*t) is real for n integer and t real */ if (mpfr_cmp_si (MPC_RE(x), -1) == 0 && mpfr_integer_p (MPC_RE(y))) z_real = 1; /* for x real, x^y is imaginary when: (a) x is negative and y is half-an-integer (b) x = -1 and Re(y) is half-an-integer */ if (mpfr_cmp_ui (MPC_RE(x), 0) < 0 && is_odd (MPC_RE(y), 1) && (y_real || mpfr_cmp_si (MPC_RE(x), -1) == 0)) z_imag = 1; } else /* x non real */ /* I^(t*I) and (-I)^(t*I) are real for t real, I^(n+t*I) and (-I)^(n+t*I) are real for n even and t real, and I^(n+t*I) and (-I)^(n+t*I) are imaginary for n odd and t real (s*I)^n is real for n even and imaginary for n odd */ if ((mpc_cmp_si_si (x, 0, 1) == 0 || mpc_cmp_si_si (x, 0, -1) == 0 || (mpfr_cmp_ui (MPC_RE(x), 0) == 0 && y_real)) && mpfr_integer_p (MPC_RE(y))) { /* x is I or -I, and Re(y) is an integer */ if (is_odd (MPC_RE(y), 0)) z_imag = 1; /* Re(y) odd: z is imaginary */ else z_real = 1; /* Re(y) even: z is real */ } else /* (t+/-t*I)^(2n) is imaginary for n odd and real for n even */ if (mpfr_cmpabs (MPC_RE(x), MPC_IM(x)) == 0 && y_real && mpfr_integer_p (MPC_RE(y)) && is_odd (MPC_RE(y), 0) == 0) { if (is_odd (MPC_RE(y), -1)) /* y/2 is odd */ z_imag = 1; else z_real = 1; } /* first bound |Re(y log(x))|, |Im(y log(x)| < 2^q */ mpc_init2 (t, 64); mpc_log (t, x, MPC_RNDNN); mpc_mul (t, t, y, MPC_RNDNN); /* the default maximum exponent for MPFR is emax=2^30-1, thus if t > log(2^emax) = emax*log(2), then exp(t) will overflow */ if (mpfr_cmp_ui_2exp (MPC_RE(t), 372130558, 1) > 0) goto overflow; /* the default minimum exponent for MPFR is emin=-2^30+1, thus the smallest representable value is 2^(emin-1), and if t < log(2^(emin-1)) = (emin-1)*log(2), then exp(t) will underflow */ if (mpfr_cmp_si_2exp (MPC_RE(t), -372130558, 1) < 0) goto underflow; q = mpfr_get_exp (MPC_RE(t)) > 0 ? mpfr_get_exp (MPC_RE(t)) : 0; if (mpfr_get_exp (MPC_IM(t)) > (mp_exp_t) q) q = mpfr_get_exp (MPC_IM(t)); pr = mpfr_get_prec (MPC_RE(z)); pi = mpfr_get_prec (MPC_IM(z)); p = (pr > pi) ? pr : pi; p += 11; /* experimentally, seems to give less than 10% of failures in Ziv's strategy */ mpc_init2 (u, p); pr += MPC_RND_RE(rnd) == GMP_RNDN; pi += MPC_RND_IM(rnd) == GMP_RNDN; maxprec = MPFR_PREC(MPC_RE(z)); if (MPFR_PREC(MPC_IM(z)) > maxprec) maxprec = MPFR_PREC(MPC_IM(z)); for (loop = 0;; loop++) { mp_exp_t dr, di; if (p + q > 64) /* otherwise we reuse the initial approximation t of y*log(x), avoiding two computations */ { mpc_set_prec (t, p + q); mpc_log (t, x, MPC_RNDNN); mpc_mul (t, t, y, MPC_RNDNN); } mpc_exp (u, t, MPC_RNDNN); /* Since the error bound is global, we have to take into account the exponent difference between the real and imaginary parts. We assume either the real or the imaginary part of u is not zero. */ dr = mpfr_zero_p (MPC_RE(u)) ? mpfr_get_exp (MPC_IM(u)) : mpfr_get_exp (MPC_RE(u)); di = mpfr_zero_p (MPC_IM(u)) ? dr : mpfr_get_exp (MPC_IM(u)); if (dr > di) { di = dr - di; dr = 0; } else { dr = di - dr; di = 0; } /* the term -3 takes into account the factor 4 in the complex error (see algorithms.tex) plus one due to the exponent difference: if z = a + I*b, where the relative error on z is at most 2^(-p), and EXP(a) = EXP(b) + k, the relative error on b is at most 2^(k-p) */ if ((z_imag || mpfr_can_round (MPC_RE(u), p - 3 - dr, GMP_RNDN, GMP_RNDZ, pr)) && (z_real || mpfr_can_round (MPC_IM(u), p - 3 - di, GMP_RNDN, GMP_RNDZ, pi))) break; /* if Re(u) is not known to be zero, assume it is a normal number, i.e., neither zero, Inf or NaN, otherwise we might enter an infinite loop */ MPC_ASSERT (z_imag || mpfr_number_p (MPC_RE(u))); /* idem for Im(u) */ MPC_ASSERT (z_real || mpfr_number_p (MPC_IM(u))); if (ret == -2) /* we did not yet call mpc_pow_exact, or it aborted because intermediate computations had > maxprec bits */ { /* check exact cases (see algorithms.tex) */ if (y_real) { maxprec *= 2; ret = mpc_pow_exact (z, x, MPC_RE(y), rnd, maxprec); if (ret != -1 && ret != -2) goto exact; } p += dr + di + 64; } else p += p / 2; mpc_set_prec (t, p + q); mpc_set_prec (u, p); } if (z_real) { /* When the result is real (see algorithm.tex for details), Im(x^y) = + sign(imag(y))*0i, if |x| > 1 + sign(imag(x))*sign(real(y))*0i, if |x| = 1 - sign(imag(y))*0i, if |x| < 1 */ mpfr_t n; int inex, cx1; int sign_zi; /* cx1 < 0 if |x| < 1 cx1 = 0 if |x| = 1 cx1 > 0 if |x| > 1 */ mpfr_init (n); inex = mpc_norm (n, x, GMP_RNDN); cx1 = mpfr_cmp_ui (n, 1); if (cx1 == 0 && inex != 0) cx1 = -inex; sign_zi = (cx1 < 0 && mpfr_signbit (MPC_IM (y)) == 0) || (cx1 == 0 && mpfr_signbit (MPC_IM (x)) != mpfr_signbit (MPC_RE (y))) || (cx1 > 0 && mpfr_signbit (MPC_IM (y))); ret = mpfr_set (MPC_RE(z), MPC_RE(u), MPC_RND_RE(rnd)); /* warning: mpfr_set_ui does not set Im(z) to -0 if Im(rnd) = RNDD */ ret = MPC_INEX (ret, mpfr_set_ui (MPC_IM (z), 0, MPC_RND_IM (rnd))); if (MPC_RND_IM (rnd) == GMP_RNDD || sign_zi) mpc_conj (z, z, MPC_RNDNN); mpfr_clear (n); } else if (z_imag) { ret = mpfr_set (MPC_IM(z), MPC_IM(u), MPC_RND_IM(rnd)); ret = MPC_INEX(mpfr_set_ui (MPC_RE(z), 0, MPC_RND_RE(rnd)), ret); } else ret = mpc_set (z, u, rnd); exact: mpc_clear (t); mpc_clear (u); end: return ret; underflow: /* If we have an underflow, we know that |z| is too small to be represented, but depending on arg(z), we should return +/-0 +/- I*0. We assume t is the approximation of y*log(x), thus we want exp(t) = exp(Re(t))+exp(I*Im(t)). FIXME: this part of code is not 100% rigorous, since we don't consider rounding errors. */ mpc_init2 (u, 64); mpfr_const_pi (MPC_RE(u), GMP_RNDN); mpfr_div_2exp (MPC_RE(u), MPC_RE(u), 1, GMP_RNDN); /* Pi/2 */ mpfr_remquo (MPC_RE(u), &Q, MPC_IM(t), MPC_RE(u), GMP_RNDN); if (mpfr_sgn (MPC_RE(u)) < 0) Q--; /* corresponds to positive remainder */ mpfr_set_ui (MPC_RE(z), 0, GMP_RNDN); mpfr_set_ui (MPC_IM(z), 0, GMP_RNDN); switch (Q & 3) { case 0: /* first quadrant: round to (+0 +0) */ ret = MPC_INEX(-1, -1); break; case 1: /* second quadrant: round to (-0 +0) */ mpfr_neg (MPC_RE(z), MPC_RE(z), GMP_RNDN); ret = MPC_INEX(1, -1); break; case 2: /* third quadrant: round to (-0 -0) */ mpfr_neg (MPC_RE(z), MPC_RE(z), GMP_RNDN); mpfr_neg (MPC_IM(z), MPC_IM(z), GMP_RNDN); ret = MPC_INEX(1, 1); break; case 3: /* fourth quadrant: round to (+0 -0) */ mpfr_neg (MPC_IM(z), MPC_IM(z), GMP_RNDN); ret = MPC_INEX(-1, 1); break; } goto clear_t_and_u; overflow: /* If we have an overflow, we know that |z| is too large to be represented, but depending on arg(z), we should return +/-Inf +/- I*Inf. We assume t is the approximation of y*log(x), thus we want exp(t) = exp(Re(t))+exp(I*Im(t)). FIXME: this part of code is not 100% rigorous, since we don't consider rounding errors. */ mpc_init2 (u, 64); mpfr_const_pi (MPC_RE(u), GMP_RNDN); mpfr_div_2exp (MPC_RE(u), MPC_RE(u), 1, GMP_RNDN); /* Pi/2 */ /* the quotient is rounded to the nearest integer in mpfr_remquo */ mpfr_remquo (MPC_RE(u), &Q, MPC_IM(t), MPC_RE(u), GMP_RNDN); if (mpfr_sgn (MPC_RE(u)) < 0) Q--; /* corresponds to positive remainder */ switch (Q & 3) { case 0: /* first quadrant */ mpfr_set_inf (MPC_RE(z), 1); mpfr_set_inf (MPC_IM(z), 1); ret = MPC_INEX(1, 1); break; case 1: /* second quadrant */ mpfr_set_inf (MPC_RE(z), -1); mpfr_set_inf (MPC_IM(z), 1); ret = MPC_INEX(-1, 1); break; case 2: /* third quadrant */ mpfr_set_inf (MPC_RE(z), -1); mpfr_set_inf (MPC_IM(z), -1); ret = MPC_INEX(-1, -1); break; case 3: /* fourth quadrant */ mpfr_set_inf (MPC_RE(z), 1); mpfr_set_inf (MPC_IM(z), -1); ret = MPC_INEX(1, -1); break; } clear_t_and_u: mpc_clear (t); mpc_clear (u); return ret; }

static bool is_vertically_higher_than ( const map_location & m1, const map_location & m2 ) { return (is_even(m1.x) && is_odd(m2.x)) ? (m1.y <= m2.y) : (m1.y < m2.y); }

TagTreeType Tag_Tree::add_attr(TagNode *tag,string &text) { //传入包含有关属性值的字符串 进行属性值的赋值 //如 "name=value name=value" //string text /*算法： trim(text) size_t s=0,e=0 string arr[] scan_text if cur==' ' or '=': arr.append(text[s..e]) s=e else e++; //判断是否为偶数 if_not_even(arr_num): return false //循环添加属性节点 ... */ // name= "value" //cout<<"add_attr()"<<endl; //cout<<"传入 attr_text "<<text<<endl; string name; string::size_type s=0,e=0; TagTreeType res; vector<string> arr; int i=0; trim(text); if(text.empty()) //text为空格 return ERROR_TAG_EMPTY_TEXT; //开始分割字符串为字符数组 while(i<text.size()) { //cout<<"attr->scaning: "<<"+>--"<<text[i]<<endl; //需要考虑引号的影响 if(text[i]=='=') { e=i; name=string(text,s,e-s); if(trim(name)) { //cout<<"attrword "<<name<<endl; arr.push_back(name); } s=e+1; i=e; } else if(text[i]=='\'') { s=i; e=text.find_first_of('\'',s+1); if(e<text.size()) { name=string(text,s,e-s+1); rm_mark(name); rm_mark(name); //cout<<"find ' "<<name<<endl; s=e+1; i=e; if(trim(name)) { //cout<<"attrword "<<name<<endl; arr.push_back(name); } } } else if(text[i]=='"') { s=i; e=text.find_first_of('"',s+1); if(e<text.size()) { name=string(text,s,e-s+1); rm_mark(name); s=e+1; i=e; if(trim(name)) { arr.push_back(name); //cout<<"attrword "<<name<<endl; } } } else if(text[i]==' ') { e=i; name=string(text,s,e-s+1); if(trim(name)) { //cout<<"attrword "<<name<<endl; arr.push_back(name); } s=e; } i++; } int size=arr.size(); if (is_odd(size)) return ERROR_TAG_STR_NOT_EVEN; //cout<<"the arrstack size "<<size<<endl; //开始循环添加属性t for(i=0;i<size;i+=2) //4 0 2 4 { cout<<"in for size "<<i<<endl; this->__append_attr(tag,arr[i],arr[i+1]); } //后续需要处理attr }//end apend_attr

int hex_display::get_location_y(const map_location& loc) const { return static_cast<int>(map_area().y + (loc.y + border_.size) * zoom_ - ypos_ + (is_odd(loc.x) ? zoom_/2 : 0)); }

/* Put in z the value of x^y, rounded according to 'rnd'. Return the inexact flag in [0, 10]. */ int mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd) { int ret = -2, loop, x_real, x_imag, y_real, z_real = 0, z_imag = 0; mpc_t t, u; mpfr_prec_t p, pr, pi, maxprec; int saved_underflow, saved_overflow; /* save the underflow or overflow flags from MPFR */ saved_underflow = mpfr_underflow_p (); saved_overflow = mpfr_overflow_p (); x_real = mpfr_zero_p (mpc_imagref(x)); y_real = mpfr_zero_p (mpc_imagref(y)); if (y_real && mpfr_zero_p (mpc_realref(y))) /* case y zero */ { if (x_real && mpfr_zero_p (mpc_realref(x))) { /* we define 0^0 to be (1, +0) since the real part is coherent with MPFR where 0^0 gives 1, and the sign of the imaginary part cannot be determined */ mpc_set_ui_ui (z, 1, 0, MPC_RNDNN); return 0; } else /* x^0 = 1 +/- i*0 even for x=NaN see algorithms.tex for the sign of zero */ { mpfr_t n; int inex, cx1; int sign_zi; /* cx1 < 0 if |x| < 1 cx1 = 0 if |x| = 1 cx1 > 0 if |x| > 1 */ mpfr_init (n); inex = mpc_norm (n, x, MPFR_RNDN); cx1 = mpfr_cmp_ui (n, 1); if (cx1 == 0 && inex != 0) cx1 = -inex; sign_zi = (cx1 < 0 && mpfr_signbit (mpc_imagref (y)) == 0) || (cx1 == 0 && mpfr_signbit (mpc_imagref (x)) != mpfr_signbit (mpc_realref (y))) || (cx1 > 0 && mpfr_signbit (mpc_imagref (y))); /* warning: mpc_set_ui_ui does not set Im(z) to -0 if Im(rnd)=RNDD */ ret = mpc_set_ui_ui (z, 1, 0, rnd); if (MPC_RND_IM (rnd) == MPFR_RNDD || sign_zi) mpc_conj (z, z, MPC_RNDNN); mpfr_clear (n); return ret; } } if (!mpc_fin_p (x) || !mpc_fin_p (y)) { /* special values: exp(y*log(x)) */ mpc_init2 (u, 2); mpc_log (u, x, MPC_RNDNN); mpc_mul (u, u, y, MPC_RNDNN); ret = mpc_exp (z, u, rnd); mpc_clear (u); goto end; } if (x_real) /* case x real */ { if (mpfr_zero_p (mpc_realref(x))) /* x is zero */ { /* special values: exp(y*log(x)) */ mpc_init2 (u, 2); mpc_log (u, x, MPC_RNDNN); mpc_mul (u, u, y, MPC_RNDNN); ret = mpc_exp (z, u, rnd); mpc_clear (u); goto end; } /* Special case 1^y = 1 */ if (mpfr_cmp_ui (mpc_realref(x), 1) == 0) { int s1, s2; s1 = mpfr_signbit (mpc_realref (y)); s2 = mpfr_signbit (mpc_imagref (x)); ret = mpc_set_ui (z, +1, rnd); /* the sign of the zero imaginary part is known in some cases (see algorithm.tex). In such cases we have (x +s*0i)^(y+/-0i) = x^y + s*sign(y)*0i where s = +/-1. We extend here this rule to fix the sign of the zero part. Note that the sign must also be set explicitly when rnd=RNDD because mpfr_set_ui(z_i, 0, rnd) always sets z_i to +0. */ if (MPC_RND_IM (rnd) == MPFR_RNDD || s1 != s2) mpc_conj (z, z, MPC_RNDNN); goto end; } /* x^y is real when: (a) x is real and y is integer (b) x is real non-negative and y is real */ if (y_real && (mpfr_integer_p (mpc_realref(y)) || mpfr_cmp_ui (mpc_realref(x), 0) >= 0)) { int s1, s2; s1 = mpfr_signbit (mpc_realref (y)); s2 = mpfr_signbit (mpc_imagref (x)); ret = mpfr_pow (mpc_realref(z), mpc_realref(x), mpc_realref(y), MPC_RND_RE(rnd)); ret = MPC_INEX(ret, mpfr_set_ui (mpc_imagref(z), 0, MPC_RND_IM(rnd))); /* the sign of the zero imaginary part is known in some cases (see algorithm.tex). In such cases we have (x +s*0i)^(y+/-0i) = x^y + s*sign(y)*0i where s = +/-1. We extend here this rule to fix the sign of the zero part. Note that the sign must also be set explicitly when rnd=RNDD because mpfr_set_ui(z_i, 0, rnd) always sets z_i to +0. */ if (MPC_RND_IM(rnd) == MPFR_RNDD || s1 != s2) mpfr_neg (mpc_imagref(z), mpc_imagref(z), MPC_RND_IM(rnd)); goto end; } /* (-1)^(n+I*t) is real for n integer and t real */ if (mpfr_cmp_si (mpc_realref(x), -1) == 0 && mpfr_integer_p (mpc_realref(y))) z_real = 1; /* for x real, x^y is imaginary when: (a) x is negative and y is half-an-integer (b) x = -1 and Re(y) is half-an-integer */ if ((mpfr_cmp_ui (mpc_realref(x), 0) < 0) && is_odd (mpc_realref(y), 1) && (y_real || mpfr_cmp_si (mpc_realref(x), -1) == 0)) z_imag = 1; } else /* x non real */ /* I^(t*I) and (-I)^(t*I) are real for t real, I^(n+t*I) and (-I)^(n+t*I) are real for n even and t real, and I^(n+t*I) and (-I)^(n+t*I) are imaginary for n odd and t real (s*I)^n is real for n even and imaginary for n odd */ if ((mpc_cmp_si_si (x, 0, 1) == 0 || mpc_cmp_si_si (x, 0, -1) == 0 || (mpfr_cmp_ui (mpc_realref(x), 0) == 0 && y_real)) && mpfr_integer_p (mpc_realref(y))) { /* x is I or -I, and Re(y) is an integer */ if (is_odd (mpc_realref(y), 0)) z_imag = 1; /* Re(y) odd: z is imaginary */ else z_real = 1; /* Re(y) even: z is real */ } else /* (t+/-t*I)^(2n) is imaginary for n odd and real for n even */ if (mpfr_cmpabs (mpc_realref(x), mpc_imagref(x)) == 0 && y_real && mpfr_integer_p (mpc_realref(y)) && is_odd (mpc_realref(y), 0) == 0) { if (is_odd (mpc_realref(y), -1)) /* y/2 is odd */ z_imag = 1; else z_real = 1; } pr = mpfr_get_prec (mpc_realref(z)); pi = mpfr_get_prec (mpc_imagref(z)); p = (pr > pi) ? pr : pi; p += 12; /* experimentally, seems to give less than 10% of failures in Ziv's strategy; probably wrong now since q is not computed */ if (p < 64) p = 64; mpc_init2 (u, p); mpc_init2 (t, p); pr += MPC_RND_RE(rnd) == MPFR_RNDN; pi += MPC_RND_IM(rnd) == MPFR_RNDN; maxprec = MPC_MAX_PREC (z); x_imag = mpfr_zero_p (mpc_realref(x)); for (loop = 0;; loop++) { int ret_exp; mpfr_exp_t dr, di; mpfr_prec_t q; mpc_log (t, x, MPC_RNDNN); mpc_mul (t, t, y, MPC_RNDNN); /* Compute q such that |Re (y log x)|, |Im (y log x)| < 2^q. We recompute it at each loop since we might get different bounds if the precision is not enough. */ q = mpfr_get_exp (mpc_realref(t)) > 0 ? mpfr_get_exp (mpc_realref(t)) : 0; if (mpfr_get_exp (mpc_imagref(t)) > (mpfr_exp_t) q) q = mpfr_get_exp (mpc_imagref(t)); mpfr_clear_overflow (); mpfr_clear_underflow (); ret_exp = mpc_exp (u, t, MPC_RNDNN); if (mpfr_underflow_p () || mpfr_overflow_p ()) { /* under- and overflow flags are set by mpc_exp */ mpc_set (z, u, MPC_RNDNN); ret = ret_exp; goto exact; } /* Since the error bound is global, we have to take into account the exponent difference between the real and imaginary parts. We assume either the real or the imaginary part of u is not zero. */ dr = mpfr_zero_p (mpc_realref(u)) ? mpfr_get_exp (mpc_imagref(u)) : mpfr_get_exp (mpc_realref(u)); di = mpfr_zero_p (mpc_imagref(u)) ? dr : mpfr_get_exp (mpc_imagref(u)); if (dr > di) { di = dr - di; dr = 0; } else { dr = di - dr; di = 0; } /* the term -3 takes into account the factor 4 in the complex error (see algorithms.tex) plus one due to the exponent difference: if z = a + I*b, where the relative error on z is at most 2^(-p), and EXP(a) = EXP(b) + k, the relative error on b is at most 2^(k-p) */ if ((z_imag || (p > q + 3 + dr && mpfr_can_round (mpc_realref(u), p - q - 3 - dr, MPFR_RNDN, MPFR_RNDZ, pr))) && (z_real || (p > q + 3 + di && mpfr_can_round (mpc_imagref(u), p - q - 3 - di, MPFR_RNDN, MPFR_RNDZ, pi)))) break; /* if Re(u) is not known to be zero, assume it is a normal number, i.e., neither zero, Inf or NaN, otherwise we might enter an infinite loop */ MPC_ASSERT (z_imag || mpfr_number_p (mpc_realref(u))); /* idem for Im(u) */ MPC_ASSERT (z_real || mpfr_number_p (mpc_imagref(u))); if (ret == -2) /* we did not yet call mpc_pow_exact, or it aborted because intermediate computations had > maxprec bits */ { /* check exact cases (see algorithms.tex) */ if (y_real) { maxprec *= 2; ret = mpc_pow_exact (z, x, mpc_realref(y), rnd, maxprec); if (ret != -1 && ret != -2) goto exact; } p += dr + di + 64; } else p += p / 2; mpc_set_prec (t, p); mpc_set_prec (u, p); } if (z_real) { /* When the result is real (see algorithm.tex for details), Im(x^y) = + sign(imag(y))*0i, if |x| > 1 + sign(imag(x))*sign(real(y))*0i, if |x| = 1 - sign(imag(y))*0i, if |x| < 1 */ mpfr_t n; int inex, cx1; int sign_zi, sign_rex, sign_imx; /* cx1 < 0 if |x| < 1 cx1 = 0 if |x| = 1 cx1 > 0 if |x| > 1 */ sign_rex = mpfr_signbit (mpc_realref (x)); sign_imx = mpfr_signbit (mpc_imagref (x)); mpfr_init (n); inex = mpc_norm (n, x, MPFR_RNDN); cx1 = mpfr_cmp_ui (n, 1); if (cx1 == 0 && inex != 0) cx1 = -inex; sign_zi = (cx1 < 0 && mpfr_signbit (mpc_imagref (y)) == 0) || (cx1 == 0 && sign_imx != mpfr_signbit (mpc_realref (y))) || (cx1 > 0 && mpfr_signbit (mpc_imagref (y))); /* copy RE(y) to n since if z==y we will destroy Re(y) below */ mpfr_set_prec (n, mpfr_get_prec (mpc_realref (y))); mpfr_set (n, mpc_realref (y), MPFR_RNDN); ret = mpfr_set (mpc_realref(z), mpc_realref(u), MPC_RND_RE(rnd)); if (y_real && (x_real || x_imag)) { /* FIXME: with y_real we assume Im(y) is really 0, which is the case for example when y comes from pow_fr, but in case Im(y) is +0 or -0, we might get different results */ mpfr_set_ui (mpc_imagref (z), 0, MPC_RND_IM (rnd)); fix_sign (z, sign_rex, sign_imx, n); ret = MPC_INEX(ret, 0); /* imaginary part is exact */ } else { ret = MPC_INEX (ret, mpfr_set_ui (mpc_imagref (z), 0, MPC_RND_IM (rnd))); /* warning: mpfr_set_ui does not set Im(z) to -0 if Im(rnd) = RNDD */ if (MPC_RND_IM (rnd) == MPFR_RNDD || sign_zi) mpc_conj (z, z, MPC_RNDNN); } mpfr_clear (n); } else if (z_imag) { ret = mpfr_set (mpc_imagref(z), mpc_imagref(u), MPC_RND_IM(rnd)); /* if z is imaginary and y real, then x cannot be real */ if (y_real && x_imag) { int sign_rex = mpfr_signbit (mpc_realref (x)); /* If z overlaps with y we set Re(z) before checking Re(y) below, but in that case y=0, which was dealt with above. */ mpfr_set_ui (mpc_realref (z), 0, MPC_RND_RE (rnd)); /* Note: fix_sign only does something when y is an integer, then necessarily y = 1 or 3 (mod 4), and in that case the sign of Im(x) is irrelevant. */ fix_sign (z, sign_rex, 0, mpc_realref (y)); ret = MPC_INEX(0, ret); } else ret = MPC_INEX(mpfr_set_ui (mpc_realref(z), 0, MPC_RND_RE(rnd)), ret); } else ret = mpc_set (z, u, rnd); exact: mpc_clear (t); mpc_clear (u); /* restore underflow and overflow flags from MPFR */ if (saved_underflow) mpfr_set_underflow (); if (saved_overflow) mpfr_set_overflow (); end: return ret; }

surface getMinimap(int w, int h, const gamemap &map, const team *vw) { const int scale = 8; DBG_DP << "creating minimap " << int(map.w()*scale*0.75) << "," << int(map.h()*scale) << "\n"; const size_t map_width = map.w()*scale*3/4; const size_t map_height = map.h()*scale; if(map_width == 0 || map_height == 0) { return surface(NULL); } surface minimap(create_neutral_surface(map_width, map_height)); if(minimap == NULL) return surface(NULL); typedef mini_terrain_cache_map cache_map; cache_map *normal_cache = &mini_terrain_cache; cache_map *fog_cache = &mini_fogged_terrain_cache; for(int y = 0; y != map.total_height(); ++y) { for(int x = 0; x != map.total_width(); ++x) { surface surf(NULL); const map_location loc(x,y); if(map.on_board(loc)) { const bool shrouded = vw != NULL && vw->shrouded(loc); // shrouded hex are not considered fogged (no need to fog a black image) const bool fogged = vw != NULL && !shrouded && vw->fogged(loc); const t_translation::t_terrain terrain = shrouded ? t_translation::VOID_TERRAIN : map[loc]; bool need_fogging = false; cache_map* cache = fogged ? fog_cache : normal_cache; cache_map::iterator i = cache->find(terrain); if (fogged && i == cache->end()) { // we don't have the fogged version in cache // try the normal cache and ask fogging the image cache = normal_cache; i = cache->find(terrain); need_fogging = true; } if(i == cache->end()) { surface tile(get_image("terrain/" + map.get_terrain_info(terrain).minimap_image() + ".png",image::HEXED)); if(tile == 0) { utils::string_map symbols; symbols["terrain"] = t_translation::write_terrain_code(terrain); const std::string msg = vgettext("Could not get image for terrain: $terrain.", symbols); VALIDATE(false, msg); } //Compose images of base and overlay if neccessary if(map.get_terrain_info(terrain).is_combined()) { surface overlay(get_image("terrain/" + map.get_terrain_info(terrain).minimap_image_overlay() + ".png", image::HEXED)); if(overlay != 0 && overlay != tile) { surface combined = create_compatible_surface(tile, tile->w, tile->h); SDL_Rect r; r.x = 0; r.y = 0; SDL_BlitSurface(tile, NULL, combined, &r); r.x = std::max(0, (tile->w - overlay->w)/2); r.y = std::max(0, (tile->h - overlay->h)/2); if ((overlay->flags & SDL_RLEACCEL) == 0) { blit_surface(overlay, NULL, combined, &r); } else { WRN_DP << map.get_terrain_info(terrain).minimap_image_overlay() << ".png overlay is RLE-encoded, creating a neutral surface\n"; surface overlay_neutral = make_neutral_surface(overlay); blit_surface(overlay_neutral, NULL, combined, &r); } tile = combined; } } surf = surface(scale_surface_blended(tile,scale,scale)); VALIDATE(surf != NULL, _("Error creating or aquiring an image.")); i = normal_cache->insert(cache_map::value_type(terrain,surf)).first; } surf = i->second; if (need_fogging) { surf = surface(adjust_surface_colour(surf,-50,-50,-50)); fog_cache->insert(cache_map::value_type(terrain,surf)); } VALIDATE(surf != NULL, _("Error creating or aquiring an image.")); // we need a balanced shift up and down of the hexes. // if not, only the bottom half-hexes are clipped // and it looks asymmetrical. // also do 1-pixel shift because the scaling // function seems to do it with its rounding SDL_Rect maprect = {x * scale*3/4 - 1, y*scale + scale/4 * (is_odd(x) ? 1 : -1) - 1, 0, 0}; SDL_BlitSurface(surf, NULL, minimap, &maprect); } } } double wratio = w*1.0 / minimap->w; double hratio = h*1.0 / minimap->h; double ratio = std::min<double>(wratio, hratio); minimap = scale_surface(minimap, static_cast<int>(minimap->w * ratio), static_cast<int>(minimap->h * ratio)); DBG_DP << "done generating minimap\n"; return minimap; }

/* Assumes that the exponent range has already been extended and if y is an integer, then the result is not exact in unbounded exponent range. */ int mpfr_pow_general (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode, int y_is_integer, mpfr_save_expo_t *expo) { mpfr_t t, u, k, absx; int neg_result = 0; int k_non_zero = 0; int check_exact_case = 0; int inexact; /* Declaration of the size variable */ mpfr_prec_t Nz = MPFR_PREC(z); /* target precision */ mpfr_prec_t Nt; /* working precision */ mpfr_exp_t err; /* error */ MPFR_ZIV_DECL (ziv_loop); MPFR_LOG_FUNC (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, mpfr_get_prec (y), mpfr_log_prec, y, rnd_mode), ("z[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (z), mpfr_log_prec, z, inexact)); /* We put the absolute value of x in absx, pointing to the significand of x to avoid allocating memory for the significand of absx. */ MPFR_ALIAS(absx, x, /*sign=*/ 1, /*EXP=*/ MPFR_EXP(x)); /* We will compute the absolute value of the result. So, let's invert the rounding mode if the result is negative. */ if (MPFR_IS_NEG (x) && is_odd (y)) { neg_result = 1; rnd_mode = MPFR_INVERT_RND (rnd_mode); } /* compute the precision of intermediary variable */ /* the optimal number of bits : see algorithms.tex */ Nt = Nz + 5 + MPFR_INT_CEIL_LOG2 (Nz); /* initialise of intermediary variable */ mpfr_init2 (t, Nt); MPFR_ZIV_INIT (ziv_loop, Nt); for (;;) { MPFR_BLOCK_DECL (flags1); /* compute exp(y*ln|x|), using MPFR_RNDU to get an upper bound, so that we can detect underflows. */ mpfr_log (t, absx, MPFR_IS_NEG (y) ? MPFR_RNDD : MPFR_RNDU); /* ln|x| */ mpfr_mul (t, y, t, MPFR_RNDU); /* y*ln|x| */ if (k_non_zero) { MPFR_LOG_MSG (("subtract k * ln(2)\n", 0)); mpfr_const_log2 (u, MPFR_RNDD); mpfr_mul (u, u, k, MPFR_RNDD); /* Error on u = k * log(2): < k * 2^(-Nt) < 1. */ mpfr_sub (t, t, u, MPFR_RNDU); MPFR_LOG_MSG (("t = y * ln|x| - k * ln(2)\n", 0)); MPFR_LOG_VAR (t); } /* estimate of the error -- see pow function in algorithms.tex. The error on t is at most 1/2 + 3*2^(EXP(t)+1) ulps, which is <= 2^(EXP(t)+3) for EXP(t) >= -1, and <= 2 ulps for EXP(t) <= -2. Additional error if k_no_zero: treal = t * errk, with 1 - |k| * 2^(-Nt) <= exp(-|k| * 2^(-Nt)) <= errk <= 1, i.e., additional absolute error <= 2^(EXP(k)+EXP(t)-Nt). Total error <= 2^err1 + 2^err2 <= 2^(max(err1,err2)+1). */ err = MPFR_NOTZERO (t) && MPFR_GET_EXP (t) >= -1 ? MPFR_GET_EXP (t) + 3 : 1; if (k_non_zero) { if (MPFR_GET_EXP (k) > err) err = MPFR_GET_EXP (k); err++; } MPFR_BLOCK (flags1, mpfr_exp (t, t, MPFR_RNDN)); /* exp(y*ln|x|)*/ /* We need to test */ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (t) || MPFR_UNDERFLOW (flags1))) { mpfr_prec_t Ntmin; MPFR_BLOCK_DECL (flags2); MPFR_ASSERTN (!k_non_zero); MPFR_ASSERTN (!MPFR_IS_NAN (t)); /* Real underflow? */ if (MPFR_IS_ZERO (t)) { /* Underflow. We computed rndn(exp(t)), where t >= y*ln|x|. Therefore rndn(|x|^y) = 0, and we have a real underflow on |x|^y. */ inexact = mpfr_underflow (z, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode, MPFR_SIGN_POS); if (expo != NULL) MPFR_SAVE_EXPO_UPDATE_FLAGS (*expo, MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW); break; } /* Real overflow? */ if (MPFR_IS_INF (t)) { /* Note: we can probably use a low precision for this test. */ mpfr_log (t, absx, MPFR_IS_NEG (y) ? MPFR_RNDU : MPFR_RNDD); mpfr_mul (t, y, t, MPFR_RNDD); /* y * ln|x| */ MPFR_BLOCK (flags2, mpfr_exp (t, t, MPFR_RNDD)); /* t = lower bound on exp(y * ln|x|) */ if (MPFR_OVERFLOW (flags2)) { /* We have computed a lower bound on |x|^y, and it overflowed. Therefore we have a real overflow on |x|^y. */ inexact = mpfr_overflow (z, rnd_mode, MPFR_SIGN_POS); if (expo != NULL) MPFR_SAVE_EXPO_UPDATE_FLAGS (*expo, MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW); break; } } k_non_zero = 1; Ntmin = sizeof(mpfr_exp_t) * CHAR_BIT; if (Ntmin > Nt) { Nt = Ntmin; mpfr_set_prec (t, Nt); } mpfr_init2 (u, Nt); mpfr_init2 (k, Ntmin); mpfr_log2 (k, absx, MPFR_RNDN); mpfr_mul (k, y, k, MPFR_RNDN); mpfr_round (k, k); MPFR_LOG_VAR (k); /* |y| < 2^Ntmin, therefore |k| < 2^Nt. */ continue; } if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - err, Nz, rnd_mode))) { inexact = mpfr_set (z, t, rnd_mode); break; } /* check exact power, except when y is an integer (since the exact cases for y integer have already been filtered out) */ if (check_exact_case == 0 && ! y_is_integer) { if (mpfr_pow_is_exact (z, absx, y, rnd_mode, &inexact)) break; check_exact_case = 1; } /* reactualisation of the precision */ MPFR_ZIV_NEXT (ziv_loop, Nt); mpfr_set_prec (t, Nt); if (k_non_zero) mpfr_set_prec (u, Nt); } MPFR_ZIV_FREE (ziv_loop); if (k_non_zero) { int inex2; long lk; /* The rounded result in an unbounded exponent range is z * 2^k. As * MPFR chooses underflow after rounding, the mpfr_mul_2si below will * correctly detect underflows and overflows. However, in rounding to * nearest, if z * 2^k = 2^(emin - 2), then the double rounding may * affect the result. We need to cope with that before overwriting z. * This can occur only if k < 0 (this test is necessary to avoid a * potential integer overflow). * If inexact >= 0, then the real result is <= 2^(emin - 2), so that * o(2^(emin - 2)) = +0 is correct. If inexact < 0, then the real * result is > 2^(emin - 2) and we need to round to 2^(emin - 1). */ MPFR_ASSERTN (MPFR_EXP_MAX <= LONG_MAX); lk = mpfr_get_si (k, MPFR_RNDN); /* Due to early overflow detection, |k| should not be much larger than * MPFR_EMAX_MAX, and as MPFR_EMAX_MAX <= MPFR_EXP_MAX/2 <= LONG_MAX/2, * an overflow should not be possible in mpfr_get_si (and lk is exact). * And one even has the following assertion. TODO: complete proof. */ MPFR_ASSERTD (lk > LONG_MIN && lk < LONG_MAX); /* Note: even in case of overflow (lk inexact), the code is correct. * Indeed, for the 3 occurrences of lk: * - The test lk < 0 is correct as sign(lk) = sign(k). * - In the test MPFR_GET_EXP (z) == __gmpfr_emin - 1 - lk, * if lk is inexact, then lk = LONG_MIN <= MPFR_EXP_MIN * (the minimum value of the mpfr_exp_t type), and * __gmpfr_emin - 1 - lk >= MPFR_EMIN_MIN - 1 - 2 * MPFR_EMIN_MIN * >= - MPFR_EMIN_MIN - 1 = MPFR_EMAX_MAX - 1. However, from the * choice of k, z has been chosen to be around 1, so that the * result of the test is false, as if lk were exact. * - In the mpfr_mul_2si (z, z, lk, rnd_mode), if lk is inexact, * then |lk| >= LONG_MAX >= MPFR_EXP_MAX, and as z is around 1, * mpfr_mul_2si underflows or overflows in the same way as if * lk were exact. * TODO: give a bound on |t|, then on |EXP(z)|. */ if (rnd_mode == MPFR_RNDN && inexact < 0 && lk < 0 && MPFR_GET_EXP (z) == __gmpfr_emin - 1 - lk && mpfr_powerof2_raw (z)) { /* Rounding to nearest, real result > z * 2^k = 2^(emin - 2), * underflow case: as the minimum precision is > 1, we will * obtain the correct result and exceptions by replacing z by * nextabove(z). */ MPFR_ASSERTN (MPFR_PREC_MIN > 1); mpfr_nextabove (z); } MPFR_CLEAR_FLAGS (); inex2 = mpfr_mul_2si (z, z, lk, rnd_mode); if (inex2) /* underflow or overflow */ { inexact = inex2; if (expo != NULL) MPFR_SAVE_EXPO_UPDATE_FLAGS (*expo, __gmpfr_flags); } mpfr_clears (u, k, (mpfr_ptr) 0); } mpfr_clear (t); /* update the sign of the result if x was negative */ if (neg_result) { MPFR_SET_NEG(z); inexact = -inexact; } return inexact; }

void test() { // check mixed int ia[] = {1, 2, 3, 4, 5, 6, 7, 8 ,9}; const unsigned sa = sizeof(ia)/sizeof(ia[0]); Iter r = std::partition(Iter(ia), Iter(ia + sa), is_odd()); assert(base(r) == ia + 5); for (int* i = ia; i < base(r); ++i) assert(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) assert(!is_odd()(*i)); // check empty r = std::partition(Iter(ia), Iter(ia), is_odd()); assert(base(r) == ia); // check all false for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i; r = std::partition(Iter(ia), Iter(ia+sa), is_odd()); assert(base(r) == ia); // check all true for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i+1; r = std::partition(Iter(ia), Iter(ia+sa), is_odd()); assert(base(r) == ia+sa); // check all true but last for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i+1; ia[sa-1] = 10; r = std::partition(Iter(ia), Iter(ia+sa), is_odd()); assert(base(r) == ia+sa-1); for (int* i = ia; i < base(r); ++i) assert(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) assert(!is_odd()(*i)); // check all true but first for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i+1; ia[0] = 10; r = std::partition(Iter(ia), Iter(ia+sa), is_odd()); assert(base(r) == ia+sa-1); for (int* i = ia; i < base(r); ++i) assert(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) assert(!is_odd()(*i)); // check all false but last for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i; ia[sa-1] = 11; r = std::partition(Iter(ia), Iter(ia+sa), is_odd()); assert(base(r) == ia+1); for (int* i = ia; i < base(r); ++i) assert(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) assert(!is_odd()(*i)); // check all false but first for (unsigned i = 0; i < sa; ++i) ia[i] = 2*i; ia[0] = 11; r = std::partition(Iter(ia), Iter(ia+sa), is_odd()); assert(base(r) == ia+1); for (int* i = ia; i < base(r); ++i) assert(is_odd()(*i)); for (int* i = base(r); i < ia+sa; ++i) assert(!is_odd()(*i)); }

inline bool is_even(const T& a) { return !is_odd(a); }

void main() { printf("hello world\n%d",is_odd(10)); }

inline bool is_even(intx x) { return !is_odd(x); }

static inline A0 cos_replacement(const A0& a0) { return One<A0>()-(is_odd(a0)<<1); // TODO << 1 is maybe bad in SSEx }

inline bool is_even(T num) { return !is_odd(num); }

inline bool is_odd(T v) { return is_odd(v, ::boost::is_convertible<T, int>()); }