This repository has been archived by the owner on Nov 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFloatingPoint.sol
48 lines (41 loc) · 2.07 KB
/
FloatingPoint.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity =0.7.6;
import {Bitmap} from "./Bitmap.sol";
import {SafeInt256} from "./SafeInt256.sol";
import {SafeUint256} from "./SafeUint256.sol";
/**
* Packs an uint value into a "floating point" storage slot. Used for storing
* lastClaimIntegralSupply values in balance storage. For these values, we don't need
* to maintain exact precision but we don't want to be limited by storage size overflows.
*
* A floating point value is defined by the 48 most significant bits and an 8 bit number
* of bit shifts required to restore its precision. The unpacked value will always be less
* than the packed value with a maximum absolute loss of precision of (2 ** bitShift) - 1.
*/
library FloatingPoint {
using SafeInt256 for int256;
using SafeUint256 for uint256;
function packTo56Bits(uint256 value) internal pure returns (uint56) {
uint256 bitShift;
// If the value is over the uint48 max value then we will shift it down
// given the index of the most significant bit. We store this bit shift
// in the least significant byte of the 56 bit slot available.
if (value > type(uint48).max) bitShift = (Bitmap.getMSB(value) - 47);
uint256 shiftedValue = value >> bitShift;
return uint56((shiftedValue << 8) | bitShift);
}
function packTo32Bits(uint256 value) internal pure returns (uint32) {
uint256 bitShift;
// If the value is over the uint24 max value then we will shift it down
// given the index of the most significant bit. We store this bit shift
// in the least significant byte of the 32 bit slot available.
if (value > type(uint24).max) bitShift = (Bitmap.getMSB(value) - 23);
uint256 shiftedValue = value >> bitShift;
return uint32((shiftedValue << 8) | bitShift);
}
function unpackFromBits(uint256 value) internal pure returns (uint256) {
// The least significant 8 bits will be the amount to bit shift
uint256 bitShift = uint256(uint8(value));
return ((value >> 8) << bitShift);
}
}