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
| 1289 | /// \param quo address to store quotient bits at |
| 1290 | /// \return Half-precision division remainder stored in single-precision |
| 1291 | static expr remquo(float x, float y, int *quo) |
| 1292 | { |
| 1293 | #if HALF_ENABLE_CPP11_CMATH |
| 1294 | return expr(std::remquo(x, y, quo)); |
| 1295 | #else |
| 1296 | if(builtin_isnan(x) || builtin_isnan(y)) |
| 1297 | return expr(std::numeric_limits<float>::quiet_NaN()); |
| 1298 | bool sign = builtin_signbit(x), qsign = static_cast<bool>(sign^builtin_signbit(y)); |
| 1299 | float ax = std::fabs(x), ay = std::fabs(y); |
| 1300 | if(ax >= 65536.0f || ay < std::ldexp(1.0f, -24)) |
| 1301 | return expr(std::numeric_limits<float>::quiet_NaN()); |
| 1302 | if(ay >= 65536.0f) |
| 1303 | return expr(x); |
| 1304 | if(ax == ay) |
| 1305 | return *quo = qsign ? -1 : 1, expr(sign ? -0.0f : 0.0f); |
| 1306 | ax = std::fmod(ax, 8.0f*ay); |
| 1307 | int cquo = 0; |
| 1308 | if(ax >= 4.0f * ay) |
| 1309 | { |
| 1310 | ax -= 4.0f * ay; |
| 1311 | cquo += 4; |
| 1312 | } |
| 1313 | if(ax >= 2.0f * ay) |
| 1314 | { |
| 1315 | ax -= 2.0f * ay; |
| 1316 | cquo += 2; |
| 1317 | } |
| 1318 | float y2 = 0.5f * ay; |
| 1319 | if(ax > y2) |
| 1320 | { |
| 1321 | ax -= ay; |
| 1322 | ++cquo; |
| 1323 | if(ax >= y2) |
| 1324 | { |
| 1325 | ax -= ay; |
| 1326 | ++cquo; |
| 1327 | } |
| 1328 | } |
| 1329 | return *quo = qsign ? -cquo : cquo, expr(sign ? -ax : ax); |
| 1330 | #endif |
| 1331 | } |
| 1332 | |
| 1333 | /// Positive difference implementation. |
| 1334 | /// \param x first operand |
nothing calls this directly
no test coverage detected