|
52 | 52 | #ifndefINT64_MAX
|
53 | 53 | #defineINT64_MAXINT64CONST(0x7FFFFFFFFFFFFFFF)
|
54 | 54 | #endif
|
| 55 | +#ifndefINT64_MIN |
| 56 | +#defineINT64_MIN(-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1) |
| 57 | +#endif |
| 58 | + |
55 | 59 |
|
56 | 60 | /*
|
57 | 61 | * Multi-platform pthread implementations
|
@@ -1510,13 +1514,37 @@ doCustom(TState *thread, CState *st, instr_time *conn_time, FILE *logfile, AggVa
|
1510 | 1514 | snprintf(res,sizeof(res),INT64_FORMAT,ope1*ope2);
|
1511 | 1515 | elseif (strcmp(argv[3],"/")==0)
|
1512 | 1516 | {
|
| 1517 | +int64operes; |
| 1518 | + |
1513 | 1519 | if (ope2==0)
|
1514 | 1520 | {
|
1515 | 1521 | fprintf(stderr,"%s: division by zero\n",argv[0]);
|
1516 | 1522 | st->ecnt++;
|
1517 | 1523 | return true;
|
1518 | 1524 | }
|
1519 |
| -snprintf(res,sizeof(res),INT64_FORMAT,ope1 /ope2); |
| 1525 | +/* |
| 1526 | + * INT64_MIN / -1 is problematic, since the result can't |
| 1527 | + * be represented on a two's-complement machine. Some |
| 1528 | + * machines produce INT64_MIN, some produce zero, some |
| 1529 | + * throw an exception. We can dodge the problem by |
| 1530 | + * recognizing that division by -1 is the same as |
| 1531 | + * negation. |
| 1532 | + */ |
| 1533 | +if (ope2==-1) |
| 1534 | +{ |
| 1535 | +operes=-ope1; |
| 1536 | + |
| 1537 | +/* overflow check (needed for INT64_MIN) */ |
| 1538 | +if (ope1==INT64_MIN) |
| 1539 | +{ |
| 1540 | +fprintf(stderr,"bigint out of range\n"); |
| 1541 | +st->ecnt++; |
| 1542 | +return true; |
| 1543 | +} |
| 1544 | +} |
| 1545 | +else |
| 1546 | +operes=ope1 /ope2; |
| 1547 | +snprintf(res,sizeof(res),INT64_FORMAT,operes); |
1520 | 1548 | }
|
1521 | 1549 | else
|
1522 | 1550 | {
|
|