int main () { int p[] = { 1, 0, 0x1, 2, 0, 0x3, 3, 0, 0x7, 4, 0, 0xf, 5, 0, 0x1f, 6, 0, 0x3f, 7, 0, 0x7f, 8, 0, 0xff, 9, 0, 0x1ff, 10, 0, 0x3ff, 11, 0, 0x7ff, 12, 0, 0xfff, 13, 0, 0x1fff, 14, 0, 0x3fff, -2, -0x2, 0x1, -3, -0x4, 0x3, -4, -0x8, 0x7, -5, -0x10, 0xf, -6, -0x20, 0x1f, -7, -0x40, 0x3f, -8, -0x80, 0x7f, -9, -0x100, 0xff, -10, -0x200, 0x1ff, -11, -0x400, 0x3ff, -12, -0x800, 0x7ff, -13, -0x1000, 0xfff, -14, -0x2000, 0x1fff }; for (int op = 0; op <= 2; op++) for (int a = 0; a < 27; ++a) for (int b = 0; b < 27; ++b) { int mina = p[3 * a + 1]; int maxa = p[3 * a + 2]; int minb = p[3 * b + 1]; int maxb = p[3 * b + 2]; int prec0 = p[3 * a]; int prec1 = p[3 * b]; long long int min, max; if (op == 0) { max = min = mina + minb; if (min > maxa + minb) min = maxa + minb; if (min > mina + maxb) min = mina + maxb; if (min > maxa + maxb) min = maxa + maxb; if (max < maxa + minb) max = maxa + minb; if (max < mina + maxb) max = mina + maxb; if (max < maxa + maxb) max = maxa + maxb; } else if (op == 1) { max = min = mina - minb; if (min > maxa - minb) min = maxa - minb; if (min > mina - maxb) min = mina - maxb; if (min > maxa - maxb) min = maxa - maxb; if (max < maxa - minb) max = maxa - minb; if (max < mina - maxb) max = mina - maxb; if (max < maxa - maxb) max = maxa - maxb; } else { max = min = ((long long) mina) * minb; if (min > ((long long) maxa) * minb) min = ((long long) maxa) * minb; if (min > ((long long) mina) * maxb) min = ((long long) mina) * maxb; if (min > ((long long) maxa) * maxb) min = ((long long) maxa) * maxb; if (max < ((long long) maxa) * minb) max = ((long long) maxa) * minb; if (max < ((long long) mina) * maxb) max = ((long long) mina) * maxb; if (max < ((long long) maxa) * maxb) max = ((long long) maxa) * maxb; } int uns = op != 1 && prec0 > 0 && prec1 > 0; int prec; if (uns) { if (min != 0) __builtin_abort (); prec = 64 - __builtin_clzll (max); } else { prec = 64 - __builtin_clrsbll (min); if (prec < 64 - __builtin_clrsbll (max)) prec = 64 - __builtin_clrsbll (max); } char buf[32]; if (min == 0) __builtin_sprintf (buf, "0"); else __builtin_sprintf (buf, "-0x%llx", -min); __builtin_printf (" %3d %c %3d [%s,0x%llx] %2d %sSIGNED\n", prec0, op == 0 ? '+' : op == 1 ? '-' : '*', prec1, buf, max, prec, uns ? "UN" : ""); #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) int prec2 = MAX (prec0 < 0 ? -prec0 : prec0, prec1 < 0 ? -prec1 : prec1); if (op != 2) prec2 = (((prec0 < 0) == (prec1 < 0) || (prec0 < 0 ? (prec2 == -prec0 && prec2 != prec1) : (prec2 == -prec1 && prec2 != prec0))) ? prec2 + 1 : prec2 + 2); if (op == 2) { prec2 = (prec0 < 0 ? -prec0 : prec0) + (prec1 < 0 ? -prec1 : prec1); if (prec0 == 1 || prec1 == 1) --prec2; } if (prec2 != prec) __builtin_abort (); } }