Multiply two nonnegative int64's, returning negative for overflow
| 24 | |
| 25 | // Multiply two nonnegative int64's, returning negative for overflow |
| 26 | inline int64 MultiplyWithoutOverflow(const int64 x, const int64 y) { |
| 27 | // Multiply in uint64 rather than int64 since signed overflow is undefined. |
| 28 | // Negative values will wrap around to large unsigned values in the casts |
| 29 | // (see section 4.7 [conv.integral] of the C++14 standard). |
| 30 | const uint64 ux = x; |
| 31 | const uint64 uy = y; |
| 32 | const uint64 uxy = ux * uy; |
| 33 | |
| 34 | // Check if we overflow uint64, using a cheap check if both inputs are small |
| 35 | if (TF_PREDICT_FALSE((ux | uy) >> 32 != 0)) { |
| 36 | // Ensure nonnegativity. Note that negative numbers will appear "large" |
| 37 | // to the unsigned comparisons above. |
| 38 | CHECK(x >= 0 && y >= 0); |
| 39 | |
| 40 | // Otherwise, detect overflow using a division |
| 41 | if (ux != 0 && uxy / ux != uy) return -1; |
| 42 | } |
| 43 | |
| 44 | // Cast back to signed. Any negative value will signal an error. |
| 45 | return static_cast<int64>(uxy); |
| 46 | } |
| 47 | |
| 48 | } // namespace tensorflow |
| 49 |
no outgoing calls