Ticket #20: BaseFunctions_Power2.diff

File BaseFunctions_Power2.diff, 5.7 kB (added by cneumann, 2 years ago)

patch

  • Source/Base/Base/OSGBaseFunctions.h

    old new  
    217217template <class TypeT> inline 
    218218bool osgispower2(TypeT rValue); 
    219219 
    220  
    221220template <class TypeT> inline 
    222221TypeT osgnextpower2(TypeT rValue); 
    223222 
    224  
    225223/*---------------------------------------------------------------------*/ 
    226224/*                    Miscellaneous Functions                          */ 
    227225 
  • Source/Base/Base/OSGBaseFunctions.inl

    old new  
    12601260    \ingroup GrpBaseBaseMathFn 
    12611261 */ 
    12621262template <> inline 
    1263 bool osgispower2<UInt32>(UInt32 rValue) 
     1263bool osgispower2<UInt32>(const UInt32 rValue) 
    12641264{ 
    1265     // find the lowest 1 bit 
    1266     while(rValue && ! (rValue & 1)) 
    1267     { 
    1268         rValue >>= 1; 
    1269     } 
     1265    return !(rValue & (rValue - 1)) && (rValue != 0); 
     1266
    12701267 
    1271     // shift the 1 bit out 
    1272     rValue >>= 1; 
     1268template <> inline 
     1269bool osgispower2<Int32>(const Int32 rValue) 
     1270
     1271    return !(rValue & (rValue - 1)) && (rValue > 0); 
     1272
    12731273 
    1274     // if another 1 left => not 2^ 
    1275     if(rValue) 
    1276         return false; 
    1277     else             
    1278         return true; 
     1274template <> inline 
     1275bool osgispower2<UInt64>(const UInt64 rValue) 
     1276
     1277    return !(rValue & (rValue - 1)) && (rValue != 0); 
    12791278} 
    12801279 
    1281 /*! Test if the argument is a power of 2 or zero. 
    1282  
    1283     \param[in] rValue Number to test, must be >= 0. 
    1284     \return true if rValue is a power of 2 or zero. 
    1285  
    1286     \ingroup GrpBaseBaseMathFn 
    1287  */ 
    12881280template <> inline 
    1289 bool osgispower2<Int32>(Int32 rValue) 
     1281bool osgispower2<Int64>(const Int64 rValue) 
    12901282{ 
    1291     // find the lowest 1 bit 
    1292     while(rValue && ! (rValue & 1)) 
    1293     { 
    1294         rValue >>= 1; 
    1295     } 
    1296  
    1297     // shift the 1 bit out 
    1298     rValue >>= 1; 
    1299  
    1300     // if another 1 left => not 2^ 
    1301     if(rValue) 
    1302         return false; 
    1303     else 
    1304         return true; 
     1283    return !(rValue & (rValue - 1)) && (rValue > 0); 
    13051284} 
    13061285 
    13071286/*! \}                                                                 */ 
     
    13201299template <> inline 
    13211300UInt32 osgnextpower2<UInt32>(UInt32 rValue) 
    13221301{ 
    1323     UInt32 result  = 1; 
    1324     UInt32 oresult = 0; 
    1325  
    1326     while(result < rValue && result > oresult) 
    1327     { 
    1328         oresult = result; 
    1329         result <<= 1; 
    1330     } 
    1331  
    1332     return (result > oresult) ? result : 0; 
     1302    if(rValue == 0) 
     1303        return TypeTraits<UInt32>::getOneElement(); 
     1304     
     1305    --rValue; 
     1306    rValue |= rValue >> 1; 
     1307    rValue |= rValue >> 2; 
     1308    rValue |= rValue >> 4; 
     1309    rValue |= rValue >> 8; 
     1310    rValue |= rValue >> 16; 
     1311    ++rValue; 
     1312     
     1313    return rValue; 
    13331314} 
    13341315 
    13351316/*! \ingroup GrpBaseBaseMathFn 
     
    13371318template <> inline 
    13381319Int32 osgnextpower2<Int32>(Int32 rValue) 
    13391320{ 
    1340     Int32 result  = 1; 
    1341     Int32 oresult = 0; 
    1342  
    1343     while(result < rValue && result > oresult) 
    1344     { 
    1345         oresult = result; 
    1346         result <<= 1; 
    1347     } 
    1348  
    1349     return (result > oresult) ? result : 0; 
     1321    const Int32 maxPower2 = TypeTraits<Int32>::getOneElement() << 30; 
     1322     
     1323    if(rValue <= 0) 
     1324        return TypeTraits<Int32>::getOneElement(); 
     1325     
     1326    // signed overflow invokes undefined behavior, avoid it. 
     1327    if(rValue > maxPower2) 
     1328        return TypeTraits<Int32>::getZeroElement(); 
     1329     
     1330    --rValue; 
     1331    rValue |= rValue >> 1; 
     1332    rValue |= rValue >> 2; 
     1333    rValue |= rValue >> 4; 
     1334    rValue |= rValue >> 8; 
     1335    rValue |= rValue >> 16; 
     1336    ++rValue; 
     1337     
     1338    return rValue; 
    13501339} 
    13511340 
    13521341/*! \ingroup GrpBaseBaseMathFn 
    13531342 */ 
    13541343template <> inline 
    1355 Int64 osgnextpower2<Int64>(Int64 rValue) 
     1344UInt64 osgnextpower2<UInt64>(UInt64 rValue) 
    13561345{ 
    1357     Int64 result  = 1; 
    1358     Int64 oresult = 0; 
    1359  
    1360     while(result < rValue && result > oresult) 
    1361     { 
    1362         oresult = result; 
    1363         result <<= 1; 
    1364     } 
    1365  
    1366     return (result > oresult) ? result : 0; 
     1346    if(rValue == 0) 
     1347        return TypeTraits<UInt64>::getOneElement(); 
     1348     
     1349    --rValue; 
     1350    rValue |= rValue >> 1; 
     1351    rValue |= rValue >> 2; 
     1352    rValue |= rValue >> 4; 
     1353    rValue |= rValue >> 8; 
     1354    rValue |= rValue >> 16; 
     1355    rValue |= rValue >> 32; 
     1356    ++rValue; 
     1357     
     1358    return rValue; 
    13671359} 
    13681360 
    13691361/*! \ingroup GrpBaseBaseMathFn 
    13701362 */ 
    13711363template <> inline 
    1372 UInt64 osgnextpower2<UInt64>(UInt64 rValue) 
     1364Int64 osgnextpower2<Int64>(Int64 rValue) 
    13731365{ 
    1374     UInt64 result  = 1; 
    1375     UInt64 oresult = 0; 
    1376  
    1377     while(result < rValue && result > oresult) 
    1378     { 
    1379         oresult = result; 
    1380         result <<= 1; 
    1381     } 
    1382  
    1383     return (result > oresult)? result : 0; 
     1366    const Int64 maxPower2 = TypeTraits<Int64>::getOneElement() << 62; 
     1367     
     1368    if(rValue <= 0) 
     1369        return TypeTraits<Int64>::getOneElement(); 
     1370     
     1371    // signed overflow invokes undefined behavior, avoid it. 
     1372    if(rValue > maxPower2) 
     1373        return TypeTraits<Int64>::getZeroElement(); 
     1374     
     1375    --rValue; 
     1376    rValue |= rValue >> 1; 
     1377    rValue |= rValue >> 2; 
     1378    rValue |= rValue >> 4; 
     1379    rValue |= rValue >> 8; 
     1380    rValue |= rValue >> 16; 
     1381    rValue |= rValue >> 32; 
     1382    ++rValue; 
     1383     
     1384    return rValue; 
    13841385} 
    13851386 
    13861387#ifdef SIZE_T_NEQ_UINT32 
     
    13901391template <> inline 
    13911392size_t osgnextpower2<size_t>(size_t rValue) 
    13921393{ 
    1393     size_t result  = 1; 
    1394     size_t oresult = 0; 
    1395  
    1396     while(result < rValue && result > oresult) 
    1397     { 
    1398         oresult = result; 
    1399         result <<= 1; 
    1400     } 
    1401  
    1402     return (result > oresult)? result : 0; 
     1394    if(rValue == 0) 
     1395        return TypeTraits<size_t>::getOneElement(); 
     1396     
     1397    --rValue; 
     1398    rValue |= rValue >> 1; 
     1399    rValue |= rValue >> 2; 
     1400    rValue |= rValue >> 4; 
     1401    rValue |= rValue >> 8; 
     1402    rValue |= rValue >> 16; 
     1403    rValue |= rValue >> 32; 
     1404    ++rValue; 
     1405     
     1406    return rValue; 
    14031407} 
    14041408 
    14051409#endif