MCPcopy Create free account
hub / github.com/OpenNMT/CTranslate2 / mod

Function mod

include/half_float/half.hpp:1409–1473  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

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);

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected