3 ms·
Looks like it is fixed now: $ expr \( -2147483648 \) \* -1 2147483648 $ expr \( -2147483648 \) / -1 2147483648 $ uname -srm FreeBSD 10.0-RELE
by Malus 12y ago
Looks like it is fixed now:
$ expr \( -2147483648 \) \* -1
2147483648
$ expr \( -2147483648 \) / -1
2147483648
$ uname -srm
FreeBSD 10.0-RELEASE amd64
Or maybe it doesn't work on i386?
- mzs 12y agoIt's likely an i386 thing: $ echo | awk '{ print 2 ** 31 }' 2147483648 Make sure you are using /bin/expr and maybe give -9223372036854775808 a whirl too.
- Malus 12y agoIt now reports overflow instead of crashing, but the first case is still incorrect: $ which expr /bin/expr $ expr \( -9223372036854775808 \) \* -1 -9223372036854775808 $ expr \( -9223372036854775808 \) / -1 expr: overflow Looking at the source code: void assert_times(intmax_t a, intmax_t b, intmax_t r) { /* * if first operand is 0, no overflow is possible, * else result of division test must match second operand */ if (a != 0 && r / a != b) errx(ERR_EXIT, "overflow"); } struct val * op_times(struct val *a, struct val *b) { struct val *r; assert_to_integer(a); assert_to_integer(b); r = make_integer(a->u.i * b->u.i); assert_times(a->u.i, b->u.i, r->u.i); free_value(a); free_value(b); return (r); } void assert_div(intmax_t a, intmax_t b) { if (b == 0) errx(ERR_EXIT, "division by zero"); /* only INTMAX_MIN / -1 causes overflow */ if (a == INTMAX_MIN && b == -1) errx(ERR_EXIT, "overflow"); } struct val * op_div(struct val *a, struct val *b) { struct val *r; assert_to_integer(a); assert_to_integer(b); /* assert based on operands only, not on result */ assert_div(a->u.i, b->u.i); r = make_integer(a->u.i / b->u.i); free_value(a); free_value(b); return (r); } Looks like the check for overflow in the multiplication case is broken since the check itself does not account for overflow. I'll try to remember to submit a patch when I get home.
- mzs 12y agothanks!