@@ -393,54 +393,38 @@ library Math {
393393 */
394394 function log2 (uint256 value ) internal pure returns (uint256 result ) {
395395 unchecked {
396- uint256 isGt ;
396+ uint256 exp ;
397397
398- assembly {
399- isGt := gt (value, 0xffffffffffffffffffffffffffffffff )
400- }
401- value >>= isGt * 128 ;
402- result += isGt * 128 ;
398+ exp = 128 * _boolToUint (value > (1 << 128 ) - 1 );
399+ value >>= exp;
400+ result += exp;
403401
404- assembly {
405- isGt := gt (value, 0xffffffffffffffff )
406- }
407- value >>= isGt * 64 ;
408- result += isGt * 64 ;
402+ exp = 64 * _boolToUint (value > (1 << 64 ) - 1 );
403+ value >>= exp;
404+ result += exp;
409405
410- assembly {
411- isGt := gt (value, 0xffffffff )
412- }
413- value >>= isGt * 32 ;
414- result += isGt * 32 ;
406+ exp = 32 * _boolToUint (value > (1 << 32 ) - 1 );
407+ value >>= exp;
408+ result += exp;
415409
416- assembly {
417- isGt := gt (value, 0xffff )
418- }
419- value >>= isGt * 16 ;
420- result += isGt * 16 ;
410+ exp = 16 * _boolToUint (value > (1 << 16 ) - 1 );
411+ value >>= exp;
412+ result += exp;
421413
422- assembly {
423- isGt := gt (value, 0xff )
424- }
425- value >>= isGt * 8 ;
426- result += isGt * 8 ;
414+ exp = 8 * _boolToUint (value > (1 << 8 ) - 1 );
415+ value >>= exp;
416+ result += exp;
427417
428- assembly {
429- isGt := gt (value, 0xf )
430- }
431- value >>= isGt * 4 ;
432- result += isGt * 4 ;
418+ exp = 4 * _boolToUint (value > (1 << 4 ) - 1 );
419+ value >>= exp;
420+ result += exp;
433421
434- assembly {
435- isGt := gt (value, 0x3 )
436- }
437- value >>= isGt * 2 ;
438- result += isGt * 2 ;
422+ exp = 2 * _boolToUint (value > (1 << 2 ) - 1 );
423+ value >>= exp;
424+ result += exp;
439425
440- assembly {
441- isGt := gt (value, 0x1 )
442- }
443- result += isGt;
426+ exp = 1 * _boolToUint (value > (1 << 1 ) - 1 );
427+ result += exp;
444428 }
445429 }
446430
@@ -553,4 +537,15 @@ library Math {
553537 function unsignedRoundsUp (Rounding rounding ) internal pure returns (bool ) {
554538 return uint8 (rounding) % 2 == 1 ;
555539 }
540+
541+ /**
542+ * @dev Convert a boolean to an integer. Returns 1 for true and 0 for false.
543+ * This function doesn't do any cleaning up, so it may only be used
544+ * with the results of operations that are known to not set the higher bits.
545+ */
546+ function _boolToUint (bool b ) private pure returns (uint256 u ) {
547+ assembly {
548+ u := b
549+ }
550+ }
556551}
0 commit comments