| 1407 | /// \param quo adress to store quotient at, `nullptr` if \a Q `false` |
| 1408 | /// \return modulus of \a x / \a y |
| 1409 | template<bool Q,bool R> unsigned int mod(unsigned int x, unsigned int y, int *quo = NULL) |
| 1410 | { |
| 1411 | unsigned int q = 0; |
| 1412 | if(x > y) |
| 1413 | { |
| 1414 | int absx = x, absy = y, expx = 0, expy = 0; |
| 1415 | for(; absx<0x400; absx<<=1,--expx) ; |
| 1416 | for(; absy<0x400; absy<<=1,--expy) ; |
| 1417 | expx += absx >> 10; |
| 1418 | expy += absy >> 10; |
| 1419 | int mx = (absx&0x3FF) | 0x400, my = (absy&0x3FF) | 0x400; |
| 1420 | for(int d=expx-expy; d; --d) |
| 1421 | { |
| 1422 | if(!Q && mx == my) |
| 1423 | return 0; |
| 1424 | if(mx >= my) |
| 1425 | { |
| 1426 | mx -= my; |
| 1427 | q += Q; |
| 1428 | } |
| 1429 | mx <<= 1; |
| 1430 | q <<= static_cast<int>(Q); |
| 1431 | } |
| 1432 | if(!Q && mx == my) |
| 1433 | return 0; |
| 1434 | if(mx >= my) |
| 1435 | { |
| 1436 | mx -= my; |
| 1437 | ++q; |
| 1438 | } |
| 1439 | if(Q) |
| 1440 | { |
| 1441 | q &= (1<<(std::numeric_limits<int>::digits-1)) - 1; |
| 1442 | if(!mx) |
| 1443 | return *quo = q, 0; |
| 1444 | } |
| 1445 | for(; mx<0x400; mx<<=1,--expy) ; |
| 1446 | x = (expy>0) ? ((expy<<10)|(mx&0x3FF)) : (mx>>(1-expy)); |
| 1447 | } |
| 1448 | if(R) |
| 1449 | { |
| 1450 | unsigned int a, b; |
| 1451 | if(y < 0x800) |
| 1452 | { |
| 1453 | a = (x<0x400) ? (x<<1) : (x+0x400); |
| 1454 | b = y; |
| 1455 | } |
| 1456 | else |
| 1457 | { |
| 1458 | a = x; |
| 1459 | b = y - 0x400; |
| 1460 | } |
| 1461 | if(a > b || (a == b && (q&1))) |
| 1462 | { |
| 1463 | int exp = (y>>10) + (y<=0x3FF), d = exp - (x>>10) - (x<=0x3FF); |
| 1464 | int m = (((y&0x3FF)|((y>0x3FF)<<10))<<1) - (((x&0x3FF)|((x>0x3FF)<<10))<<(1-d)); |
| 1465 | for(; m<0x800 && exp>1; m<<=1,--exp) ; |
| 1466 | x = 0x8000 + ((exp-1)<<10) + (m>>1); |
nothing calls this directly
no outgoing calls
no test coverage detected