Remainder implementation. \param x first operand \param y second operand \param quo address to store quotient bits at \return Half-precision division remainder stored in single-precision
| 1302 | /// \param quo address to store quotient bits at |
| 1303 | /// \return Half-precision division remainder stored in single-precision |
| 1304 | static expr remquo(float x, float y, int *quo) |
| 1305 | { |
| 1306 | #if HALF_ENABLE_CPP11_CMATH |
| 1307 | return expr(std::remquo(x, y, quo)); |
| 1308 | #else |
| 1309 | if(builtin_isnan(x) || builtin_isnan(y)) |
| 1310 | return expr(std::numeric_limits<float>::quiet_NaN()); |
| 1311 | bool sign = builtin_signbit(x), qsign = static_cast<bool>(sign^builtin_signbit(y)); |
| 1312 | float ax = std::fabs(x), ay = std::fabs(y); |
| 1313 | if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24)) |
| 1314 | return expr(std::numeric_limits<float>::quiet_NaN()); |
| 1315 | if(ay >= 65536.0f) |
| 1316 | return expr(x); |
| 1317 | if(ax == ay) |
| 1318 | return *quo = qsign ? -1 : 1, expr(sign ? -0.0f : 0.0f); |
| 1319 | ax = std::fmod(ax, 8.0f*ay); |
| 1320 | int cquo = 0; |
| 1321 | if(ax >= 4.0f * ay) |
| 1322 | { |
| 1323 | ax -= 4.0f * ay; |
| 1324 | cquo += 4; |
| 1325 | } |
| 1326 | if(ax >= 2.0f * ay) |
| 1327 | { |
| 1328 | ax -= 2.0f * ay; |
| 1329 | cquo += 2; |
| 1330 | } |
| 1331 | float y2 = 0.5f * ay; |
| 1332 | if(ax > y2) |
| 1333 | { |
| 1334 | ax -= ay; |
| 1335 | ++cquo; |
| 1336 | if(ax >= y2) |
| 1337 | { |
| 1338 | ax -= ay; |
| 1339 | ++cquo; |
| 1340 | } |
| 1341 | } |
| 1342 | return *quo = qsign ? -cquo : cquo, expr(sign ? -ax : ax); |
| 1343 | #endif |
| 1344 | } |
| 1345 | |
| 1346 | /// Positive difference implementation. |
| 1347 | /// \param x first operand |
nothing calls this directly
no test coverage detected