Ticket #20: BaseFunctions_Power2.diff
| File BaseFunctions_Power2.diff, 5.7 kB (added by cneumann, 2 years ago) |
|---|
-
Source/Base/Base/OSGBaseFunctions.h
old new 217 217 template <class TypeT> inline 218 218 bool osgispower2(TypeT rValue); 219 219 220 221 220 template <class TypeT> inline 222 221 TypeT osgnextpower2(TypeT rValue); 223 222 224 225 223 /*---------------------------------------------------------------------*/ 226 224 /* Miscellaneous Functions */ 227 225 -
Source/Base/Base/OSGBaseFunctions.inl
old new 1260 1260 \ingroup GrpBaseBaseMathFn 1261 1261 */ 1262 1262 template <> inline 1263 bool osgispower2<UInt32>( UInt32 rValue)1263 bool osgispower2<UInt32>(const UInt32 rValue) 1264 1264 { 1265 // find the lowest 1 bit 1266 while(rValue && ! (rValue & 1)) 1267 { 1268 rValue >>= 1; 1269 } 1265 return !(rValue & (rValue - 1)) && (rValue != 0); 1266 } 1270 1267 1271 // shift the 1 bit out 1272 rValue >>= 1; 1268 template <> inline 1269 bool osgispower2<Int32>(const Int32 rValue) 1270 { 1271 return !(rValue & (rValue - 1)) && (rValue > 0); 1272 } 1273 1273 1274 // if another 1 left => not 2^ 1275 if(rValue) 1276 return false; 1277 else 1278 return true; 1274 template <> inline 1275 bool osgispower2<UInt64>(const UInt64 rValue) 1276 { 1277 return !(rValue & (rValue - 1)) && (rValue != 0); 1279 1278 } 1280 1279 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 GrpBaseBaseMathFn1287 */1288 1280 template <> inline 1289 bool osgispower2<Int 32>(Int32rValue)1281 bool osgispower2<Int64>(const Int64 rValue) 1290 1282 { 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); 1305 1284 } 1306 1285 1307 1286 /*! \} */ … … 1320 1299 template <> inline 1321 1300 UInt32 osgnextpower2<UInt32>(UInt32 rValue) 1322 1301 { 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; 1333 1314 } 1334 1315 1335 1316 /*! \ingroup GrpBaseBaseMathFn … … 1337 1318 template <> inline 1338 1319 Int32 osgnextpower2<Int32>(Int32 rValue) 1339 1320 { 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; 1350 1339 } 1351 1340 1352 1341 /*! \ingroup GrpBaseBaseMathFn 1353 1342 */ 1354 1343 template <> inline 1355 Int64 osgnextpower2<Int64>(Int64 rValue)1344 UInt64 osgnextpower2<UInt64>(UInt64 rValue) 1356 1345 { 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; 1367 1359 } 1368 1360 1369 1361 /*! \ingroup GrpBaseBaseMathFn 1370 1362 */ 1371 1363 template <> inline 1372 UInt64 osgnextpower2<UInt64>(UInt64 rValue)1364 Int64 osgnextpower2<Int64>(Int64 rValue) 1373 1365 { 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; 1384 1385 } 1385 1386 1386 1387 #ifdef SIZE_T_NEQ_UINT32 … … 1390 1391 template <> inline 1391 1392 size_t osgnextpower2<size_t>(size_t rValue) 1392 1393 { 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; 1403 1407 } 1404 1408 1405 1409 #endif
