From e966d5aafbefa2ed5c4725766739f7ff596afadd Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Sun, 10 Aug 2025 21:56:36 +0400 Subject: [PATCH 01/14] ceil --- .gas-snapshot | 388 +++++++++--------- src/lib/LibDecimalFloat.sol | 23 ++ .../LibDecimalFloatImplementation.sol | 59 ++- test/src/lib/LibDecimalFloat.ceil.t.sol | 105 +++++ test/src/lib/LibDecimalFloat.pow.t.sol | 2 +- test/src/lib/LibDecimalFloat.sqrt.t.sol | 4 +- .../LibDecimalFloatImplementation.add.t.sol | 139 ++++--- .../LibDecimalFloatImplementation.log10.t.sol | 16 +- .../LibDecimalFloatImplementation.pow10.t.sol | 11 +- 9 files changed, 469 insertions(+), 278 deletions(-) create mode 100644 test/src/lib/LibDecimalFloat.ceil.t.sol diff --git a/.gas-snapshot b/.gas-snapshot index 03124789..00245815 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,140 +1,146 @@ -DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5100, μ: 2447356, ~: 2447298) -DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5100, μ: 2450111, ~: 2449802) -DecimalFloatConstantsTest:testEDeployed() (gas: 2446563) -DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2446595) -DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2446531) -DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2446506) -DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2446485) -DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5100, μ: 2449855, ~: 2449711) -DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5100, μ: 2447762, ~: 2447688) -DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5100, μ: 2447560, ~: 2447543) -DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5100, μ: 2451379, ~: 2451202) -DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5100, μ: 2447608, ~: 2447591) -DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5100, μ: 2448162, ~: 2448095) -DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5100, μ: 2448648, ~: 2448565) -DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5100, μ: 2447683, ~: 2447608) -DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5100, μ: 2447755, ~: 2447681) -DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5100, μ: 2448946, ~: 2448871) -DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5100, μ: 2446873, ~: 2446873) -DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5100, μ: 2447660, ~: 2447585) -DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5100, μ: 2447713, ~: 2447638) -DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5100, μ: 2447743, ~: 2447682) -DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5100, μ: 2447742, ~: 2447680) -DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5100, μ: 2447433, ~: 2447433) -DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5100, μ: 2449642, ~: 2450705) -DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5100, μ: 158769, ~: 158769) -DecimalFloatParseTest:testParseDeployed(string) (runs: 5100, μ: 2450176, ~: 2450045) -DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5100, μ: 2457813, ~: 2455719) -DecimalFloatPowTest:testSqrtDeployed(bytes32) (runs: 5100, μ: 2457126, ~: 2456425) -DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5100, μ: 2450443, ~: 2450140) -DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5100, μ: 2448786, ~: 2448678) -DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5100, μ: 2448935, ~: 2449207) -LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5100, μ: 5121, ~: 5121) -LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5100, μ: 10475, ~: 10702) -LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5100, μ: 9641, ~: 9392) +DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5108, μ: 2492261, ~: 2492203) +DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5108, μ: 2503699, ~: 2496973) +DecimalFloatConstantsTest:testEDeployed() (gas: 2491468) +DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2491500) +DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2491436) +DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2491411) +DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2491390) +DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5108, μ: 2494759, ~: 2494616) +DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5108, μ: 2492668, ~: 2492593) +DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5108, μ: 2492121, ~: 2491936) +DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5108, μ: 2496271, ~: 2496107) +DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5108, μ: 2492512, ~: 2492496) +DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5108, μ: 2493068, ~: 2493000) +DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5108, μ: 2493557, ~: 2493470) +DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5108, μ: 2492588, ~: 2492513) +DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5108, μ: 2492661, ~: 2492586) +DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5108, μ: 2493853, ~: 2493776) +DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5108, μ: 2491778, ~: 2491778) +DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5108, μ: 2492565, ~: 2492490) +DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5108, μ: 2492618, ~: 2492543) +DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5108, μ: 2492649, ~: 2492587) +DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5108, μ: 2492646, ~: 2492585) +DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5108, μ: 2492338, ~: 2492338) +DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5108, μ: 2494551, ~: 2495610) +DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5108, μ: 158769, ~: 158769) +DecimalFloatParseTest:testParseDeployed(string) (runs: 5108, μ: 2495080, ~: 2494950) +DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5108, μ: 2511030, ~: 2500616) +DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5108, μ: 2509995, ~: 2501330) +DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5108, μ: 2503984, ~: 2497305) +DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5108, μ: 2493686, ~: 2493583) +DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5108, μ: 2493832, ~: 2494112) +LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5107, μ: 5121, ~: 5121) +LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5108, μ: 10475, ~: 10702) +LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5108, μ: 9641, ~: 9392) +LibDecimalFloatCeilTest:testCeilExamples() (gas: 118610) +LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5108, μ: 12359, ~: 11055) +LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5108, μ: 9944, ~: 9807) +LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5108, μ: 8955, ~: 9216) +LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5108, μ: 583, ~: 411) +LibDecimalFloatCeilTest:testCeilZero(int32) (runs: 5108, μ: 5438, ~: 5438) LibDecimalFloatConstantsTest:testFloatE() (gas: 3357) LibDecimalFloatConstantsTest:testFloatHalf() (gas: 3336) LibDecimalFloatConstantsTest:testFloatMaxNegativeValue() (gas: 3379) -LibDecimalFloatConstantsTest:testFloatMaxNegativeValueIsMax(bytes32) (runs: 5100, μ: 4488, ~: 4594) +LibDecimalFloatConstantsTest:testFloatMaxNegativeValueIsMax(bytes32) (runs: 5108, μ: 4488, ~: 4594) LibDecimalFloatConstantsTest:testFloatMaxPositiveValue() (gas: 3335) -LibDecimalFloatConstantsTest:testFloatMaxPositiveValueIsMax(bytes32) (runs: 5100, μ: 3545, ~: 3586) +LibDecimalFloatConstantsTest:testFloatMaxPositiveValueIsMax(bytes32) (runs: 5108, μ: 3545, ~: 3586) LibDecimalFloatConstantsTest:testFloatMinNegativeValue() (gas: 3335) -LibDecimalFloatConstantsTest:testFloatMinNegativeValueIsMin(bytes32) (runs: 5100, μ: 3496, ~: 3457) +LibDecimalFloatConstantsTest:testFloatMinNegativeValueIsMin(bytes32) (runs: 5108, μ: 3496, ~: 3457) LibDecimalFloatConstantsTest:testFloatMinPositiveValue() (gas: 3357) -LibDecimalFloatConstantsTest:testFloatMinPositiveValueIsMin(bytes32) (runs: 5100, μ: 4938, ~: 4870) +LibDecimalFloatConstantsTest:testFloatMinPositiveValueIsMin(bytes32) (runs: 5108, μ: 4938, ~: 4870) LibDecimalFloatConstantsTest:testFloatOne() (gas: 3358) LibDecimalFloatConstantsTest:testFloatTwo() (gas: 3380) LibDecimalFloatConstantsTest:testFloatZero() (gas: 3337) -LibDecimalFloatDecimalAddTest:testAddPacked(bytes32,bytes32) (runs: 5100, μ: 8361, ~: 8036) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5100, μ: 9615, ~: 9663) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5100, μ: 8130, ~: 8048) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5100, μ: 7452, ~: 7424) +LibDecimalFloatDecimalAddTest:testAddPacked(bytes32,bytes32) (runs: 5108, μ: 16977, ~: 10308) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5103, μ: 9615, ~: 9663) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5108, μ: 8130, ~: 8048) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5108, μ: 7452, ~: 7424) LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessFail() (gas: 4894) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPacked(bytes32,uint8) (runs: 5100, μ: 6717, ~: 6161) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5100, μ: 15805, ~: 15768) -LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5100, μ: 9274, ~: 9053) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPacked(bytes32,uint8) (runs: 5108, μ: 6718, ~: 6161) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5108, μ: 15805, ~: 15768) +LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5108, μ: 9274, ~: 9053) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyComplicated() (gas: 685958) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMax() (gas: 673506) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMaxPlusOne() (gas: 704362) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOne() (gas: 685936) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOneMillion() (gas: 685937) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOverflow() (gas: 715261) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyPacked(uint256,uint8) (runs: 5100, μ: 9460, ~: 9374) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5100, μ: 5978, ~: 5937) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5100, μ: 7305, ~: 5860) -LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5099, μ: 16005, ~: 15996) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5100, μ: 14963, ~: 14729) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5100, μ: 10152, ~: 9811) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5100, μ: 10825, ~: 11076) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyPacked(bytes32,uint8) (runs: 5100, μ: 6804, ~: 6905) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5097, μ: 15348, ~: 15612) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5100, μ: 14493, ~: 14212) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyPacked(uint256,uint8) (runs: 5108, μ: 9460, ~: 9374) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5108, μ: 5978, ~: 5937) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5108, μ: 7306, ~: 5860) +LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5101, μ: 16005, ~: 15996) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5108, μ: 14964, ~: 14729) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5108, μ: 10151, ~: 9811) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5108, μ: 10825, ~: 11076) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyPacked(bytes32,uint8) (runs: 5108, μ: 6805, ~: 6905) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5103, μ: 15348, ~: 15612) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5108, μ: 14493, ~: 14212) LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncateLossless() (gas: 14523) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5100, μ: 13738, ~: 13602) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5100, μ: 4598, ~: 4598) -LibDecimalFloatDivTest:testDivPacked(bytes32,bytes32) (runs: 5100, μ: 8052, ~: 7855) -LibDecimalFloatEqTest:testEqPacked(bytes32,bytes32) (runs: 5100, μ: 5524, ~: 5450) -LibDecimalFloatEqTest:testEqXNotYExponents(bytes32,bytes32) (runs: 5100, μ: 4341, ~: 4234) -LibDecimalFloatEqTest:testEqZero(int32) (runs: 5100, μ: 5133, ~: 5133) -LibDecimalFloatFloorTest:testFloorExamples() (gas: 38974) -LibDecimalFloatFloorTest:testFloorGas0() (gas: 937) -LibDecimalFloatFloorTest:testFloorGasTiny() (gas: 858) -LibDecimalFloatFloorTest:testFloorGasZero() (gas: 809) -LibDecimalFloatFloorTest:testFloorInRange(int224,int256) (runs: 5100, μ: 11009, ~: 11021) -LibDecimalFloatFloorTest:testFloorLessThanMin(int224,int256) (runs: 5100, μ: 10261, ~: 10270) -LibDecimalFloatFloorTest:testFloorNonNegative(int224,int256) (runs: 5100, μ: 9803, ~: 10062) -LibDecimalFloatFloorTest:testFloorNotReverts(bytes32) (runs: 5100, μ: 630, ~: 621) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5108, μ: 13739, ~: 13602) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5108, μ: 4598, ~: 4598) +LibDecimalFloatDivTest:testDivPacked(bytes32,bytes32) (runs: 5108, μ: 8052, ~: 7855) +LibDecimalFloatEqTest:testEqPacked(bytes32,bytes32) (runs: 5108, μ: 5524, ~: 5450) +LibDecimalFloatEqTest:testEqXNotYExponents(bytes32,bytes32) (runs: 5108, μ: 4341, ~: 4234) +LibDecimalFloatEqTest:testEqZero(int32) (runs: 5108, μ: 5133, ~: 5133) +LibDecimalFloatFloorTest:testFloorExamples() (gas: 38387) +LibDecimalFloatFloorTest:testFloorGas0() (gas: 960) +LibDecimalFloatFloorTest:testFloorGasTiny() (gas: 881) +LibDecimalFloatFloorTest:testFloorGasZero() (gas: 553) +LibDecimalFloatFloorTest:testFloorInRange(int224,int256) (runs: 5108, μ: 11032, ~: 11044) +LibDecimalFloatFloorTest:testFloorLessThanMin(int224,int256) (runs: 5108, μ: 10284, ~: 10293) +LibDecimalFloatFloorTest:testFloorNonNegative(int224,int256) (runs: 5108, μ: 9547, ~: 9806) +LibDecimalFloatFloorTest:testFloorNotReverts(bytes32) (runs: 5108, μ: 461, ~: 365) LibDecimalFloatFracTest:testFracExamples() (gas: 39135) LibDecimalFloatFracTest:testFracGas0() (gas: 960) LibDecimalFloatFracTest:testFracGasTiny() (gas: 836) LibDecimalFloatFracTest:testFracGasZero() (gas: 820) -LibDecimalFloatFracTest:testFracInRange(int224,int256) (runs: 5100, μ: 10847, ~: 10859) -LibDecimalFloatFracTest:testFracLessThanMin(int224,int256) (runs: 5100, μ: 10273, ~: 10280) -LibDecimalFloatFracTest:testFracNonNegative(int224,int256) (runs: 5100, μ: 9805, ~: 10066) -LibDecimalFloatFracTest:testFracNotReverts(bytes32) (runs: 5100, μ: 630, ~: 621) +LibDecimalFloatFracTest:testFracInRange(int224,int256) (runs: 5108, μ: 10847, ~: 10859) +LibDecimalFloatFracTest:testFracLessThanMin(int224,int256) (runs: 5108, μ: 10273, ~: 10280) +LibDecimalFloatFracTest:testFracNonNegative(int224,int256) (runs: 5108, μ: 9806, ~: 10066) +LibDecimalFloatFracTest:testFracNotReverts(bytes32) (runs: 5108, μ: 630, ~: 621) LibDecimalFloatGtTest:testGtGasAZero() (gas: 973) LibDecimalFloatGtTest:testGtGasBZero() (gas: 973) LibDecimalFloatGtTest:testGtGasBothZero() (gas: 751) LibDecimalFloatGtTest:testGtGasDifferentSigns() (gas: 974) LibDecimalFloatGtTest:testGtGasExponentDiffOverflow() (gas: 1143) -LibDecimalFloatGtTest:testGtOneEAny(bytes32) (runs: 5100, μ: 3494, ~: 3494) -LibDecimalFloatGtTest:testGtReference(int224,int32,int224,int32) (runs: 5100, μ: 8065, ~: 6272) -LibDecimalFloatGtTest:testGtX(int224,int32) (runs: 5100, μ: 3882, ~: 3882) -LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int32,int32) (runs: 5100, μ: 10592, ~: 10332) -LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5100, μ: 11144, ~: 11349) -LibDecimalFloatGtTest:testGtXNotY(bytes32,bytes32) (runs: 5100, μ: 4341, ~: 4232) -LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int32,int256,int32) (runs: 5100, μ: 13764, ~: 13595) -LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int32,int32) (runs: 5100, μ: 10273, ~: 10026) -LibDecimalFloatGtTest:testGtZero(int32,int32) (runs: 5100, μ: 4793, ~: 4793) +LibDecimalFloatGtTest:testGtOneEAny(bytes32) (runs: 5108, μ: 3494, ~: 3494) +LibDecimalFloatGtTest:testGtReference(int224,int32,int224,int32) (runs: 5108, μ: 8064, ~: 6272) +LibDecimalFloatGtTest:testGtX(int224,int32) (runs: 5108, μ: 3882, ~: 3882) +LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int32,int32) (runs: 5108, μ: 10593, ~: 10332) +LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5108, μ: 11144, ~: 11349) +LibDecimalFloatGtTest:testGtXNotY(bytes32,bytes32) (runs: 5108, μ: 4341, ~: 4232) +LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int32,int256,int32) (runs: 5108, μ: 13764, ~: 13595) +LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int32,int32) (runs: 5108, μ: 10274, ~: 10026) +LibDecimalFloatGtTest:testGtZero(int32,int32) (runs: 5108, μ: 4793, ~: 4793) LibDecimalFloatGteTest:testGteGasAZero() (gas: 976) LibDecimalFloatGteTest:testGteGasBZero() (gas: 1020) LibDecimalFloatGteTest:testGteGasBothZero() (gas: 753) LibDecimalFloatGteTest:testGteGasDifferentSigns() (gas: 996) LibDecimalFloatGteTest:testGteGasExponentDiffOverflow() (gas: 1102) -LibDecimalFloatGteTest:testGteOneEAny(bytes32) (runs: 5100, μ: 3494, ~: 3494) -LibDecimalFloatGteTest:testGteReference(int224,int32,int224,int32) (runs: 5100, μ: 8115, ~: 6344) -LibDecimalFloatGteTest:testGteX(int224,int32) (runs: 5100, μ: 3925, ~: 3925) -LibDecimalFloatGteTest:testGteXEAnyVsXEAny(int256,int32,int32) (runs: 5100, μ: 10622, ~: 10364) -LibDecimalFloatGteTest:testGteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5100, μ: 11156, ~: 11361) -LibDecimalFloatGteTest:testGteXNotLtY(bytes32,bytes32) (runs: 5100, μ: 3947, ~: 3873) -LibDecimalFloatGteTest:testGteXPositiveYNegative(int256,int32,int256,int32) (runs: 5100, μ: 13794, ~: 13623) -LibDecimalFloatGteTest:testGteXPositiveYZero(int256,int32,int32) (runs: 5100, μ: 9551, ~: 9170) -LibDecimalFloatGteTest:testGteZero(int32,int32) (runs: 5100, μ: 4838, ~: 4838) -LibDecimalFloatImplementationAddTest:testAdd123456789987654321() (gas: 4813) -LibDecimalFloatImplementationAddTest:testAdd123456789e9987654321() (gas: 4865) -LibDecimalFloatImplementationAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5100, μ: 13213, ~: 13134) -LibDecimalFloatImplementationAddTest:testAddOneOneNotNormalized() (gas: 5368) -LibDecimalFloatImplementationAddTest:testAddOneOnePreNormalized() (gas: 4250) -LibDecimalFloatImplementationAddTest:testAddOneZero() (gas: 3688) -LibDecimalFloatImplementationAddTest:testAddSameExponentSameCoefficient(int256,int256) (runs: 5100, μ: 5764, ~: 5813) -LibDecimalFloatImplementationAddTest:testAddZero() (gas: 3664) -LibDecimalFloatImplementationAddTest:testAddZeroAnyExponent(int128) (runs: 5100, μ: 9294, ~: 9271) -LibDecimalFloatImplementationAddTest:testAddZeroOne() (gas: 3686) -LibDecimalFloatImplementationAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5100, μ: 14015, ~: 14005) -LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeExamples() (gas: 19289) -LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5098, μ: 17092, ~: 17016) -LibDecimalFloatImplementationAddTest:testGasAddOne() (gas: 944) -LibDecimalFloatImplementationAddTest:testGasAddZero() (gas: 382) +LibDecimalFloatGteTest:testGteOneEAny(bytes32) (runs: 5108, μ: 3494, ~: 3494) +LibDecimalFloatGteTest:testGteReference(int224,int32,int224,int32) (runs: 5108, μ: 8114, ~: 6344) +LibDecimalFloatGteTest:testGteX(int224,int32) (runs: 5108, μ: 3925, ~: 3925) +LibDecimalFloatGteTest:testGteXEAnyVsXEAny(int256,int32,int32) (runs: 5108, μ: 10622, ~: 10364) +LibDecimalFloatGteTest:testGteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5108, μ: 11156, ~: 11361) +LibDecimalFloatGteTest:testGteXNotLtY(bytes32,bytes32) (runs: 5108, μ: 3947, ~: 3873) +LibDecimalFloatGteTest:testGteXPositiveYNegative(int256,int32,int256,int32) (runs: 5108, μ: 13794, ~: 13623) +LibDecimalFloatGteTest:testGteXPositiveYZero(int256,int32,int32) (runs: 5108, μ: 9551, ~: 9170) +LibDecimalFloatGteTest:testGteZero(int32,int32) (runs: 5108, μ: 4838, ~: 4838) +LibDecimalFloatImplementationAddTest:testAdd123456789987654321() (gas: 13762) +LibDecimalFloatImplementationAddTest:testAdd123456789e9987654321() (gas: 13814) +LibDecimalFloatImplementationAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5108, μ: 19288, ~: 19407) +LibDecimalFloatImplementationAddTest:testAddOneOneNotMaximized() (gas: 15721) +LibDecimalFloatImplementationAddTest:testAddOneOnePreMaximized() (gas: 4181) +LibDecimalFloatImplementationAddTest:testAddOneZero() (gas: 3666) +LibDecimalFloatImplementationAddTest:testAddSameExponentSameCoefficient(int256,int256) (runs: 5108, μ: 12503, ~: 12450) +LibDecimalFloatImplementationAddTest:testAddZero() (gas: 3687) +LibDecimalFloatImplementationAddTest:testAddZeroAnyExponent(int128) (runs: 5108, μ: 9293, ~: 9271) +LibDecimalFloatImplementationAddTest:testAddZeroOne() (gas: 3664) +LibDecimalFloatImplementationAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5107, μ: 13988, ~: 13961) +LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeExamples() (gas: 204071) +LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5100, μ: 29701, ~: 30074) +LibDecimalFloatImplementationAddTest:testGasAddOne() (gas: 6283) +LibDecimalFloatImplementationAddTest:testGasAddZero() (gas: 360) LibDecimalFloatImplementationDivTest:testDiv1Over3() (gas: 6014) LibDecimalFloatImplementationDivTest:testDiv1Over3Gas0() (gas: 716) LibDecimalFloatImplementationDivTest:testDiv1Over3Gas10() (gas: 6907) @@ -144,120 +150,120 @@ LibDecimalFloatImplementationDivTest:testDivNegative1Over3() (gas: 6074) LibDecimalFloatImplementationDivTest:testDivOOMs5and2() (gas: 4848) LibDecimalFloatImplementationDivTest:testDivOOMsOverTen() (gas: 5665) LibDecimalFloatImplementationDivTest:testDivTenOverOOMs() (gas: 5590) -LibDecimalFloatImplementationDivTest:testUnnormalizedThreesDiv0(int256,int256) (runs: 104, μ: 21050734, ~: 21050370) +LibDecimalFloatImplementationDivTest:testUnnormalizedThreesDiv0(int256,int256) (runs: 112, μ: 21050742, ~: 21050370) LibDecimalFloatImplementationEqTest:testEqGasAZero() (gas: 430) LibDecimalFloatImplementationEqTest:testEqGasBZero() (gas: 473) LibDecimalFloatImplementationEqTest:testEqGasBothZero() (gas: 450) LibDecimalFloatImplementationEqTest:testEqGasDifferentSigns() (gas: 482) LibDecimalFloatImplementationEqTest:testEqGasExponentDiffOverflow() (gas: 533) -LibDecimalFloatImplementationEqTest:testEqNotReverts(int256,int256,int256,int256) (runs: 5100, μ: 654, ~: 679) -LibDecimalFloatImplementationEqTest:testEqOneEAny(int256,int256) (runs: 5100, μ: 3416, ~: 3416) -LibDecimalFloatImplementationEqTest:testEqReference(int256,int256,int256,int256) (runs: 5100, μ: 9905, ~: 11456) -LibDecimalFloatImplementationEqTest:testEqX(int256) (runs: 5100, μ: 3392, ~: 3392) -LibDecimalFloatImplementationEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5100, μ: 4718, ~: 4714) -LibDecimalFloatImplementationEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5100, μ: 732, ~: 753) -LibDecimalFloatImplementationEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5100, μ: 3928, ~: 3953) -LibDecimalFloatImplementationEqTest:testEqZero(int256,int256) (runs: 5100, μ: 3440, ~: 3440) +LibDecimalFloatImplementationEqTest:testEqNotReverts(int256,int256,int256,int256) (runs: 5108, μ: 654, ~: 679) +LibDecimalFloatImplementationEqTest:testEqOneEAny(int256,int256) (runs: 5108, μ: 3416, ~: 3416) +LibDecimalFloatImplementationEqTest:testEqReference(int256,int256,int256,int256) (runs: 5108, μ: 9901, ~: 11437) +LibDecimalFloatImplementationEqTest:testEqX(int256) (runs: 5108, μ: 3392, ~: 3392) +LibDecimalFloatImplementationEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5106, μ: 4718, ~: 4714) +LibDecimalFloatImplementationEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5108, μ: 732, ~: 753) +LibDecimalFloatImplementationEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5108, μ: 3928, ~: 3953) +LibDecimalFloatImplementationEqTest:testEqZero(int256,int256) (runs: 5108, μ: 3440, ~: 3440) LibDecimalFloatImplementationInvTest:testInvGas0() (gas: 734) -LibDecimalFloatImplementationInvTest:testInvReference(int256,int256) (runs: 5100, μ: 12224, ~: 12163) +LibDecimalFloatImplementationInvTest:testInvReference(int256,int256) (runs: 5106, μ: 12225, ~: 12163) LibDecimalFloatImplementationInvTest:testInvSlowGas0() (gas: 755) -LibDecimalFloatImplementationLog10Test:testExactLogs() (gas: 1263200) -LibDecimalFloatImplementationLog10Test:testExactLookups() (gas: 1280292) -LibDecimalFloatImplementationLog10Test:testInterpolatedLookups() (gas: 1257728) -LibDecimalFloatImplementationLog10Test:testSub1() (gas: 1255242) -LibDecimalFloatImplementationMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5100, μ: 12951, ~: 12929) +LibDecimalFloatImplementationLog10Test:testExactLogs() (gas: 1263178) +LibDecimalFloatImplementationLog10Test:testExactLookupsLog10() (gas: 1324402) +LibDecimalFloatImplementationLog10Test:testInterpolatedLookups() (gas: 1285189) +LibDecimalFloatImplementationLog10Test:testSub1() (gas: 1271435) +LibDecimalFloatImplementationMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5108, μ: 12953, ~: 12929) LibDecimalFloatImplementationMulTest:testMul123456789987654321() (gas: 3676) -LibDecimalFloatImplementationMulTest:testMul123456789987654321WithExponents(int128,int128) (runs: 5100, μ: 13186, ~: 13270) +LibDecimalFloatImplementationMulTest:testMul123456789987654321WithExponents(int128,int128) (runs: 5108, μ: 13185, ~: 13270) LibDecimalFloatImplementationMulTest:testMul1e181e19() (gas: 3720) LibDecimalFloatImplementationMulTest:testMulGasOne() (gas: 382) LibDecimalFloatImplementationMulTest:testMulGasZero() (gas: 324) -LibDecimalFloatImplementationMulTest:testMulNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5100, μ: 13394, ~: 12563) +LibDecimalFloatImplementationMulTest:testMulNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5108, μ: 13394, ~: 12563) LibDecimalFloatImplementationMulTest:testMulOneOne() (gas: 3721) LibDecimalFloatImplementationMulTest:testMulOneZero() (gas: 3663) LibDecimalFloatImplementationMulTest:testMulZero0Exponent() (gas: 3620) -LibDecimalFloatImplementationMulTest:testMulZeroAnyExponent(int64,int64) (runs: 5100, μ: 3908, ~: 3908) +LibDecimalFloatImplementationMulTest:testMulZeroAnyExponent(int64,int64) (runs: 5108, μ: 3908, ~: 3908) LibDecimalFloatImplementationMulTest:testMulZeroOne() (gas: 3642) LibDecimalFloatImplementationNormalizeTest:testExamples() (gas: 160899) -LibDecimalFloatImplementationNormalizeTest:testIdempotent(int256,int256) (runs: 5100, μ: 9875, ~: 9808) -LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5100, μ: 3533, ~: 3539) -LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5100, μ: 9415, ~: 9348) +LibDecimalFloatImplementationNormalizeTest:testIdempotent(int256,int256) (runs: 5108, μ: 9875, ~: 9808) +LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5108, μ: 3533, ~: 3539) +LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5108, μ: 9415, ~: 9348) LibDecimalFloatImplementationPow10Test:testExactLookups() (gas: 1281984) LibDecimalFloatImplementationPow10Test:testExactPows() (gas: 1260129) -LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1277254) -LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 5100, μ: 1258254, ~: 1259171) -LibDecimalFloatImplementationSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5100, μ: 16004, ~: 15967) -LibDecimalFloatImplementationSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5100, μ: 16216, ~: 16148) +LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1369862) +LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 5102, μ: 1270532, ~: 1268592) +LibDecimalFloatImplementationSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5108, μ: 28253, ~: 28480) +LibDecimalFloatImplementationSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5108, μ: 21162, ~: 22944) LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentExamples() (gas: 13429) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5097, μ: 14426, ~: 14395) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5100, μ: 13307, ~: 13527) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5100, μ: 11668, ~: 11718) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5100, μ: 3676, ~: 3676) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5099, μ: 13874, ~: 13665) -LibDecimalFloatInvTest:testInvMem(bytes32) (runs: 5100, μ: 7321, ~: 7246) -LibDecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5100, μ: 3899, ~: 3899) -LibDecimalFloatIsZeroTest:testIsZeroEqZero(bytes32) (runs: 5100, μ: 3527, ~: 3527) -LibDecimalFloatIsZeroTest:testIsZeroExamples(int32) (runs: 5100, μ: 4477, ~: 4477) -LibDecimalFloatIsZeroTest:testNotIsZero(int224,int32) (runs: 5100, μ: 3896, ~: 3896) -LibDecimalFloatLog10Test:testLog10Packed(bytes32) (runs: 5100, μ: 1646008, ~: 1263823) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5101, μ: 14426, ~: 14395) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5108, μ: 13307, ~: 13527) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5108, μ: 11668, ~: 11718) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5108, μ: 3676, ~: 3676) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5103, μ: 13874, ~: 13665) +LibDecimalFloatInvTest:testInvMem(bytes32) (runs: 5108, μ: 7321, ~: 7246) +LibDecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5108, μ: 3899, ~: 3899) +LibDecimalFloatIsZeroTest:testIsZeroEqZero(bytes32) (runs: 5108, μ: 3527, ~: 3527) +LibDecimalFloatIsZeroTest:testIsZeroExamples(int32) (runs: 5108, μ: 4477, ~: 4477) +LibDecimalFloatIsZeroTest:testNotIsZero(int224,int32) (runs: 5106, μ: 3896, ~: 3896) +LibDecimalFloatLog10Test:testLog10Packed(bytes32) (runs: 5108, μ: 1676566, ~: 1319587) LibDecimalFloatLtTest:testLtExamples() (gas: 3994) LibDecimalFloatLtTest:testLtGasAZero() (gas: 946) LibDecimalFloatLtTest:testLtGasBZero() (gas: 1012) LibDecimalFloatLtTest:testLtGasBothZero() (gas: 969) LibDecimalFloatLtTest:testLtGasDifferentSigns() (gas: 969) LibDecimalFloatLtTest:testLtGasExponentDiffOverflow() (gas: 1053) -LibDecimalFloatLtTest:testLtNegativeVsPositive(int256,int32,int256,int32) (runs: 5100, μ: 13750, ~: 13593) -LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int32,int32) (runs: 5100, μ: 10790, ~: 11008) -LibDecimalFloatLtTest:testLtOneEAny(int224,int32) (runs: 5100, μ: 3905, ~: 3905) -LibDecimalFloatLtTest:testLtReference(bytes32,bytes32) (runs: 5100, μ: 4696, ~: 4998) -LibDecimalFloatLtTest:testLtVsEqualVsGt(bytes32,bytes32) (runs: 5100, μ: 4323, ~: 4210) -LibDecimalFloatLtTest:testLtX(int224) (runs: 5100, μ: 3798, ~: 3798) -LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int32,int32) (runs: 5100, μ: 10557, ~: 10297) -LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5100, μ: 11153, ~: 11359) -LibDecimalFloatLtTest:testLtZero(int32,int32) (runs: 5100, μ: 4171, ~: 4171) +LibDecimalFloatLtTest:testLtNegativeVsPositive(int256,int32,int256,int32) (runs: 5108, μ: 13750, ~: 13593) +LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int32,int32) (runs: 5108, μ: 10790, ~: 11008) +LibDecimalFloatLtTest:testLtOneEAny(int224,int32) (runs: 5108, μ: 3905, ~: 3905) +LibDecimalFloatLtTest:testLtReference(bytes32,bytes32) (runs: 5108, μ: 4697, ~: 4998) +LibDecimalFloatLtTest:testLtVsEqualVsGt(bytes32,bytes32) (runs: 5108, μ: 4323, ~: 4210) +LibDecimalFloatLtTest:testLtX(int224) (runs: 5108, μ: 3798, ~: 3798) +LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int32,int32) (runs: 5108, μ: 10557, ~: 10297) +LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5108, μ: 11153, ~: 11359) +LibDecimalFloatLtTest:testLtZero(int32,int32) (runs: 5108, μ: 4171, ~: 4171) LibDecimalFloatLteTest:testLteGasAZero() (gas: 997) LibDecimalFloatLteTest:testLteGasBZero() (gas: 999) LibDecimalFloatLteTest:testLteGasBothZero() (gas: 753) LibDecimalFloatLteTest:testLteGasDifferentSigns() (gas: 976) LibDecimalFloatLteTest:testLteGasExponentDiffOverflow() (gas: 1082) -LibDecimalFloatLteTest:testLteOneEAny(bytes32) (runs: 5100, μ: 3493, ~: 3493) -LibDecimalFloatLteTest:testLteReference(int224,int32,int224,int32) (runs: 5100, μ: 8110, ~: 6315) -LibDecimalFloatLteTest:testLteX(int224,int32) (runs: 5100, μ: 3904, ~: 3904) -LibDecimalFloatLteTest:testLteXEAnyVsXEAny(int256,int32,int32) (runs: 5100, μ: 10582, ~: 10321) -LibDecimalFloatLteTest:testLteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5100, μ: 11177, ~: 11383) -LibDecimalFloatLteTest:testLteXNotLtY(bytes32,bytes32) (runs: 5100, μ: 3882, ~: 3807) -LibDecimalFloatLteTest:testLteXPositiveYNegative(int256,int32,int256,int32) (runs: 5100, μ: 13102, ~: 12931) -LibDecimalFloatLteTest:testLteXPositiveYZero(int256,int32,int32) (runs: 5100, μ: 9575, ~: 9191) -LibDecimalFloatLteTest:testLteZero(int32,int32) (runs: 5100, μ: 4816, ~: 4816) -LibDecimalFloatMaxTest:testMaxX(bytes32) (runs: 5100, μ: 4246, ~: 4246) -LibDecimalFloatMaxTest:testMaxXY(bytes32,bytes32) (runs: 5100, μ: 4689, ~: 4613) -LibDecimalFloatMaxTest:testMaxXYEqual(bytes32) (runs: 5100, μ: 5272, ~: 5272) -LibDecimalFloatMaxTest:testMaxXYGreater(bytes32,bytes32) (runs: 5098, μ: 6129, ~: 6016) -LibDecimalFloatMaxTest:testMaxXYLess(bytes32,bytes32) (runs: 5098, μ: 6141, ~: 6027) -LibDecimalFloatMinTest:testMinX(bytes32) (runs: 5100, μ: 4268, ~: 4268) -LibDecimalFloatMinTest:testMinXY(bytes32,bytes32) (runs: 5100, μ: 4689, ~: 4613) -LibDecimalFloatMinTest:testMinXYEqual(bytes32) (runs: 5100, μ: 5292, ~: 5292) -LibDecimalFloatMinTest:testMinXYGreater(bytes32,bytes32) (runs: 5098, μ: 6074, ~: 5961) -LibDecimalFloatMinTest:testMinXYLess(bytes32,bytes32) (runs: 5098, μ: 6087, ~: 5972) -LibDecimalFloatMinusTest:testMinusPacked(bytes32) (runs: 5100, μ: 5550, ~: 5550) +LibDecimalFloatLteTest:testLteOneEAny(bytes32) (runs: 5108, μ: 3493, ~: 3493) +LibDecimalFloatLteTest:testLteReference(int224,int32,int224,int32) (runs: 5108, μ: 8109, ~: 6315) +LibDecimalFloatLteTest:testLteX(int224,int32) (runs: 5108, μ: 3904, ~: 3904) +LibDecimalFloatLteTest:testLteXEAnyVsXEAny(int256,int32,int32) (runs: 5108, μ: 10582, ~: 10321) +LibDecimalFloatLteTest:testLteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5108, μ: 11177, ~: 11383) +LibDecimalFloatLteTest:testLteXNotLtY(bytes32,bytes32) (runs: 5108, μ: 3882, ~: 3807) +LibDecimalFloatLteTest:testLteXPositiveYNegative(int256,int32,int256,int32) (runs: 5108, μ: 13103, ~: 12931) +LibDecimalFloatLteTest:testLteXPositiveYZero(int256,int32,int32) (runs: 5108, μ: 9575, ~: 9191) +LibDecimalFloatLteTest:testLteZero(int32,int32) (runs: 5108, μ: 4816, ~: 4816) +LibDecimalFloatMaxTest:testMaxX(bytes32) (runs: 5108, μ: 4246, ~: 4246) +LibDecimalFloatMaxTest:testMaxXY(bytes32,bytes32) (runs: 5108, μ: 4689, ~: 4613) +LibDecimalFloatMaxTest:testMaxXYEqual(bytes32) (runs: 5108, μ: 5272, ~: 5272) +LibDecimalFloatMaxTest:testMaxXYGreater(bytes32,bytes32) (runs: 5103, μ: 6129, ~: 6016) +LibDecimalFloatMaxTest:testMaxXYLess(bytes32,bytes32) (runs: 5101, μ: 6141, ~: 6027) +LibDecimalFloatMinTest:testMinX(bytes32) (runs: 5108, μ: 4268, ~: 4268) +LibDecimalFloatMinTest:testMinXY(bytes32,bytes32) (runs: 5108, μ: 4689, ~: 4613) +LibDecimalFloatMinTest:testMinXYEqual(bytes32) (runs: 5108, μ: 5292, ~: 5292) +LibDecimalFloatMinTest:testMinXYGreater(bytes32,bytes32) (runs: 5104, μ: 6074, ~: 5961) +LibDecimalFloatMinTest:testMinXYLess(bytes32,bytes32) (runs: 5100, μ: 6087, ~: 5972) +LibDecimalFloatMinusTest:testMinusPacked(bytes32) (runs: 5108, μ: 5550, ~: 5550) LibDecimalFloatMixedTest:testDiv1Over3() (gas: 8161) -LibDecimalFloatMulTest:testMulPacked(bytes32,bytes32) (runs: 5100, μ: 7890, ~: 8837) -LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5100, μ: 5352, ~: 5352) -LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5100, μ: 1644444, ~: 1257918) -LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5100, μ: 1248393, ~: 1248360) -LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 5100, μ: 1246472, ~: 1246472) -LibDecimalFloatPowTest:testPowAZeroNegative(bytes32) (runs: 5097, μ: 1246804, ~: 1246804) -LibDecimalFloatPowTest:testPowBZero(bytes32,int32) (runs: 5100, μ: 1246036, ~: 1246036) -LibDecimalFloatPowTest:testPows() (gas: 1296960) -LibDecimalFloatPowTest:testRoundTripFuzz(bytes32,bytes32) (runs: 5100, μ: 1257241, ~: 1253651) -LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1450811) -LibDecimalFloatSqrtTest:testRoundTripFuzz(int224,int32) (runs: 5100, μ: 1282810, ~: 1281348) -LibDecimalFloatSqrtTest:testSqrt() (gas: 1287510) -LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5100, μ: 1248099, ~: 1248059) -LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1372610) -LibDecimalFloatSubTest:testSubPacked(bytes32,bytes32) (runs: 5100, μ: 8614, ~: 8297) +LibDecimalFloatMulTest:testMulPacked(bytes32,bytes32) (runs: 5108, μ: 7891, ~: 8837) +LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5108, μ: 5352, ~: 5352) +LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5108, μ: 1646693, ~: 1276690) +LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5108, μ: 1248480, ~: 1248447) +LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 5102, μ: 1246471, ~: 1246471) +LibDecimalFloatPowTest:testPowAZeroNegative(bytes32) (runs: 5098, μ: 1246870, ~: 1246870) +LibDecimalFloatPowTest:testPowBZero(bytes32,int32) (runs: 5108, μ: 1246058, ~: 1246058) +LibDecimalFloatPowTest:testPows() (gas: 1360903) +LibDecimalFloatPowTest:testRoundTripFuzzPow(bytes32,bytes32) (runs: 5108, μ: 1285399, ~: 1281267) +LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1672185) +LibDecimalFloatSqrtTest:testRoundTripFuzzSqrt(int224,int32) (runs: 5108, μ: 1346450, ~: 1335395) +LibDecimalFloatSqrtTest:testSqrt() (gas: 1331739) +LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5108, μ: 1248101, ~: 1248059) +LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1547274) +LibDecimalFloatSubTest:testSubPacked(bytes32,bytes32) (runs: 5108, μ: 17219, ~: 10557) LibFormatDecimalFloatTest:testFormatDecimalExamples() (gas: 133439) -LibFormatDecimalFloatTest:testFormatDecimalRoundTrip(uint256) (runs: 5100, μ: 25221, ~: 20105) -LibFormatDecimalFloatTest:testFormatDecimalRoundTripNegative(int256) (runs: 5100, μ: 19679, ~: 21006) +LibFormatDecimalFloatTest:testFormatDecimalRoundTrip(uint256) (runs: 5108, μ: 25219, ~: 20105) +LibFormatDecimalFloatTest:testFormatDecimalRoundTripNegative(int256) (runs: 5108, μ: 19679, ~: 21006) LibLogTableBytesTest:testToBytesAntiLogTableDec() (gas: 159794) LibLogTableBytesTest:testToBytesAntiLogTableDecSmall() (gas: 162322) LibLogTableBytesTest:testToBytesLogTableDec() (gas: 143165) @@ -279,7 +285,7 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatEDot() (gas: 4190) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert5() (gas: 4176) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert6() (gas: 4188) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponents() (gas: 402635) -LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5100, μ: 45906, ~: 37364) +LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5108, μ: 45908, ~: 37394) LibParseDecimalFloatTest:testParseLiteralDecimalFloatLeadingZeros() (gas: 59779) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeE() (gas: 6100) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeFrac() (gas: 5137) @@ -287,5 +293,5 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert0() (gas: 27 LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert1() (gas: 24801) LibParseDecimalFloatTest:testParseLiteralDecimalFloatSpecific() (gas: 22959) LibParseDecimalFloatTest:testParseLiteralDecimalFloatUnrelated() (gas: 50856) -LibParseDecimalFloatTest:testParsePacked(string) (runs: 5100, μ: 9787, ~: 9668) -TestDecimalFloatUnpackTest:testUnpackDeployed(bytes32) (runs: 5100, μ: 158422, ~: 158422) \ No newline at end of file +LibParseDecimalFloatTest:testParsePacked(string) (runs: 5108, μ: 9786, ~: 9668) +TestDecimalFloatUnpackTest:testUnpackDeployed(bytes32) (runs: 5108, μ: 158422, ~: 158422) \ No newline at end of file diff --git a/src/lib/LibDecimalFloat.sol b/src/lib/LibDecimalFloat.sol index 75d5255c..525971a0 100644 --- a/src/lib/LibDecimalFloat.sol +++ b/src/lib/LibDecimalFloat.sol @@ -612,6 +612,10 @@ library LibDecimalFloat { /// @param float The float to floor. function floor(Float float) internal pure returns (Float) { (int256 signedCoefficient, int256 exponent) = float.unpack(); + // If the exponent is 0 or greater then the float is already an integer. + if (exponent >= 0) { + return float; + } (int256 characteristic, int256 mantissa) = LibDecimalFloatImplementation.characteristicMantissa(signedCoefficient, exponent); (Float result, bool lossless) = packLossy(characteristic, exponent); @@ -620,6 +624,25 @@ library LibDecimalFloat { return result; } + /// Smallest integer value greater than or equal to the float. + /// @param float The float to ceil. + function ceil(Float float) internal pure returns (Float) { + (int256 signedCoefficient, int256 exponent) = float.unpack(); + // If the exponent is 0 or greater then the float is already an integer. + if (exponent >= 0) { + return float; + } + (int256 characteristic, int256 mantissa) = + LibDecimalFloatImplementation.characteristicMantissa(signedCoefficient, exponent); + (Float result, bool lossless) = packLossy(characteristic, exponent); + if (mantissa > 0) { + result = add(result, FLOAT_ONE); + } + // Ceiling is lossy by definition. + (lossless, mantissa); + return result; + } + /// Same as power10, but accepts a Float struct instead of separate values. /// Costs more gas but helps mitigate stack depth issues, and is more /// ergonomic for the caller. diff --git a/src/lib/implementation/LibDecimalFloatImplementation.sol b/src/lib/implementation/LibDecimalFloatImplementation.sol index f6a7d2eb..562179bc 100644 --- a/src/lib/implementation/LibDecimalFloatImplementation.sol +++ b/src/lib/implementation/LibDecimalFloatImplementation.sol @@ -13,7 +13,7 @@ import {LibDecimalFloat} from "../LibDecimalFloat.sol"; error WithTargetExponentOverflow(int256 signedCoefficient, int256 exponent, int256 targetExponent); -uint256 constant ADD_MAX_EXPONENT_DIFF = 37; +uint256 constant ADD_MAX_EXPONENT_DIFF = 76; /// @dev The maximum exponent that can be normalized. /// This is crazy large, so should never be a problem for any real use case. @@ -56,6 +56,11 @@ int256 constant NORMALIZED_ZERO_SIGNED_COEFFICIENT = 0; /// @dev The exponent of zero when normalized. int256 constant NORMALIZED_ZERO_EXPONENT = 0; +/// @dev The signed coefficient of maximized zero. +int256 constant MAXIMIZED_ZERO_SIGNED_COEFFICIENT = NORMALIZED_ZERO_SIGNED_COEFFICIENT; +/// @dev The exponent of maximized zero. +int256 constant MAXIMIZED_ZERO_EXPONENT = NORMALIZED_ZERO_EXPONENT; + library LibDecimalFloatImplementation { /// Negates and normalizes a float. /// Equivalent to `0 - x`. @@ -270,11 +275,11 @@ library LibDecimalFloatImplementation { } } - // Normalizing A and B gives us similar coefficients, which simplifies + // Maximizing A and B gives us similar coefficients, which simplifies // detecting when their exponents are too far apart to add without // simply ignoring one of them. - (signedCoefficientA, exponentA) = normalize(signedCoefficientA, exponentA); - (signedCoefficientB, exponentB) = normalize(signedCoefficientB, exponentB); + (signedCoefficientA, exponentA) = maximize(signedCoefficientA, exponentA); + (signedCoefficientB, exponentB) = maximize(signedCoefficientB, exponentB); // We want A to represent the larger exponent. If this is not the case // then swap them. @@ -288,30 +293,27 @@ library LibDecimalFloatImplementation { exponentB = tmp; } - // After normalization the signed coefficients are the same OOM in + // After maximization the signed coefficients are the same OOM in // magnitude. However, what we need is for the exponents to be the same. - // If the exponents are close enough we can multiply coefficient A by + // If the exponents are close enough we can divide coefficient B by // some power of 10 to align their exponents without precision loss. // If the exponents are too far apart, then all the information in B - // would be lost by the final normalization step, so we can just ignore - // B and return A. - uint256 multiplier; + // would be lost, so we can just ignore B and return A. unchecked { uint256 alignmentExponentDiff = uint256(exponentA - exponentB); // The early return here allows us to do unchecked pow on the - // multiplier and means we never revert due to overflow here. + // scaler and means we never revert due to overflow here. if (alignmentExponentDiff > ADD_MAX_EXPONENT_DIFF) { return (signedCoefficientA, exponentA); } - multiplier = 10 ** alignmentExponentDiff; + signedCoefficientB /= int256(10 ** alignmentExponentDiff); } - signedCoefficientA *= int256(multiplier); // The actual addition step. unchecked { signedCoefficientA += signedCoefficientB; } - return (signedCoefficientA, exponentB); + return (signedCoefficientA, exponentA); } /// @param signedCoefficientA The signed coefficient of the first floating @@ -523,6 +525,37 @@ library LibDecimalFloatImplementation { } } + function maximize(int256 signedCoefficient, int256 exponent) internal pure returns (int256, int256) { + unchecked { + if (signedCoefficient == 0) { + return (MAXIMIZED_ZERO_SIGNED_COEFFICIENT, MAXIMIZED_ZERO_EXPONENT); + } + int256 initialExponent = exponent; + + if (signedCoefficient / 1e76 != 0) { + signedCoefficient /= 10; + exponent += 1; + + if (exponent < initialExponent) { + revert ExponentOverflow(signedCoefficient, exponent); + } + } else { + while (signedCoefficient / 1e75 == 0) { + // This is a "jump down" in the exponent, so we can multiply + // the coefficient by 10 and decrease the exponent by 1. + signedCoefficient *= 10; + exponent -= 1; + } + + if (initialExponent < exponent) { + revert ExponentOverflow(signedCoefficient, exponent); + } + } + + return (signedCoefficient, exponent); + } + } + function isNormalized(int256 signedCoefficient, int256 exponent) internal pure returns (bool) { bool result; uint256 normalizedMaxPlusOne = NORMALIZED_MAX_PLUS_ONE; diff --git a/test/src/lib/LibDecimalFloat.ceil.t.sol b/test/src/lib/LibDecimalFloat.ceil.t.sol new file mode 100644 index 00000000..e4adf22b --- /dev/null +++ b/test/src/lib/LibDecimalFloat.ceil.t.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +import {LibDecimalFloat, Float} from "src/lib/LibDecimalFloat.sol"; +import {LibDecimalFloatImplementation} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; + +import {Test, console2} from "forge-std/Test.sol"; + +contract LibDecimalFloatCeilTest is Test { + using LibDecimalFloat for Float; + + function testCeilNotReverts(Float x) external pure { + x.ceil(); + } + + function checkCeil(int256 x, int256 exponent, int256 expectedSignedCoefficient, int256 expectedExponent) + internal + pure + { + (x, exponent) = LibDecimalFloat.ceil(LibDecimalFloat.packLossless(x, exponent)).unpack(); + + if (!LibDecimalFloatImplementation.eq(x, exponent, expectedSignedCoefficient, expectedExponent)) { + console2.log("x", x); + console2.log("exponent", exponent); + console2.log("expectedSignedCoefficient", expectedSignedCoefficient); + console2.log("expectedExponent", expectedExponent); + revert("Ceil check failed"); + } + } + + /// Every non negative exponent is identity for ceil. + function testCeilNonNegative(int224 x, int256 exponent) external pure { + exponent = bound(exponent, 0, type(int32).max); + checkCeil(x, exponent, x, exponent); + } + + /// If the exponent is less than -76 then the ceil is 1 if x is positive, + /// or 0 if x is negative. + function testCeilLessThanMin(int224 x, int256 exponent) external pure { + exponent = bound(exponent, type(int32).min, -77); + if (x <= 0) { + checkCeil(x, exponent, 0, exponent); + } else { + checkCeil(x, exponent, 1, 0); + } + } + + /// For exponents [-76,-1] the ceil is the + 1. + function testCeilInRange(int224 x, int256 exponent) external pure { + exponent = bound(exponent, -76, -1); + int256 scale = int256(10 ** uint256(-exponent)); + + int256 characteristic = x / scale; + console2.logInt(characteristic); + if (characteristic == 0) { + if (x > 0) { + // If the characteristic is 0 and x is positive then the ceil is 1. + checkCeil(x, exponent, 1, 0); + } else { + // If the characteristic is 0 and x is negative then the ceil is 0. + checkCeil(x, exponent, 0, exponent); + } + } else { + // If the characteristic is non-zero then we can just add 1 to it + // if the mantissa is non-zero. + int256 mantissa = x % scale; + if (mantissa > 0) { + // If the mantissa is greater than 0, we need to add 1 to + // the characteristic to get the ceiling. + characteristic += 1; + } + checkCeil(x, exponent, characteristic * scale, exponent); + } + } + + /// Examples + function testCeilExamples() external pure { + checkCeil(123456789, 0, 123456789, 0); + checkCeil(123456789, -1, 12345679000000000000000000000000000000000000000000000000000000000000, -60); + checkCeil(123456789, -2, 12345680000000000000000000000000000000000000000000000000000000000000, -61); + checkCeil(123456789, -3, 12345700000000000000000000000000000000000000000000000000000000000000, -62); + checkCeil(123456789, -4, 12346000000000000000000000000000000000000000000000000000000000000000, -63); + checkCeil(123456789, -5, 12350000000000000000000000000000000000000000000000000000000000000000, -64); + checkCeil(123456789, -6, 12400000000000000000000000000000000000000000000000000000000000000000, -65); + checkCeil(123456789, -7, 13000000000000000000000000000000000000000000000000000000000000000000, -66); + checkCeil(123456789, -8, 2000000000000000000000000000000000000000000000000000000000000000000, -66); + checkCeil(123456789, -9, 1, 0); + checkCeil(123456789, -10, 1, 0); + checkCeil(123456789, -11, 1, 0); + checkCeil(type(int224).max, 0, type(int224).max, 0); + checkCeil(type(int224).min, 0, type(int224).min, 0); + checkCeil(2.5e37, -37, 3e66, -66); + checkCeil(type(int224).max, 0, type(int224).max, 0); + } + + /// Test some zeros. + function testCeilZero(int32 exponent) external pure { + Float wrapZero = Float.wrap(0); + Float packZeroBasic = LibDecimalFloat.packLossless(0, 0); + Float packZero = LibDecimalFloat.packLossless(0, exponent); + assertTrue(wrapZero.ceil().eq(packZero)); + assertTrue(wrapZero.ceil().eq(packZeroBasic)); + assertEq(Float.unwrap(wrapZero.ceil()), Float.unwrap(packZeroBasic)); + } +} diff --git a/test/src/lib/LibDecimalFloat.pow.t.sol b/test/src/lib/LibDecimalFloat.pow.t.sol index 909b717c..6829f7bb 100644 --- a/test/src/lib/LibDecimalFloat.pow.t.sol +++ b/test/src/lib/LibDecimalFloat.pow.t.sol @@ -125,7 +125,7 @@ contract LibDecimalFloatPowTest is LogTest { return a.pow(b, logTables()); } - function testRoundTripFuzz(Float a, Float b) external { + function testRoundTripFuzzPow(Float a, Float b) external { try this.powExternal(a, b) returns (Float c) { // If b is zero we'll divide by zero on the inv. // If c is 1 then it's not round trippable because 1^x = 1 for all x. diff --git a/test/src/lib/LibDecimalFloat.sqrt.t.sol b/test/src/lib/LibDecimalFloat.sqrt.t.sol index de91a4cf..ec56d5b9 100644 --- a/test/src/lib/LibDecimalFloat.sqrt.t.sol +++ b/test/src/lib/LibDecimalFloat.sqrt.t.sol @@ -53,7 +53,7 @@ contract LibDecimalFloatSqrtTest is LogTest { checkSqrt(0, 0, 0, 0); checkSqrt(2, 0, 1415, -3); checkSqrt(4, 0, 2e3, -3); - checkSqrt(16, 0, 399950000000000000000000000000000000000000, -41); + checkSqrt(16, 0, 3999500000000000000000000000000000000000000000000000000000000000000, -66); } function testSqrtNegative(Float a) external { @@ -84,7 +84,7 @@ contract LibDecimalFloatSqrtTest is LogTest { checkRoundTrip(100000000, 0); } - function testRoundTripFuzz(int224 signedCoefficient, int32 exponent) external { + function testRoundTripFuzzSqrt(int224 signedCoefficient, int32 exponent) external { signedCoefficient = int224(bound(signedCoefficient, 1, type(int224).max)); exponent = int32(bound(exponent, type(int16).min, type(int16).max)); checkRoundTrip(signedCoefficient, exponent); diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.add.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.add.t.sol index 3a1fab8d..1351a283 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.add.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.add.t.sol @@ -10,6 +10,20 @@ import { import {Test} from "forge-std/Test.sol"; contract LibDecimalFloatImplementationAddTest is Test { + function checkAdd( + int256 signedCoefficientA, + int256 exponentA, + int256 signedCoefficientB, + int256 exponentB, + int256 expectedSignedCoefficient, + int256 expectedExponent + ) internal pure { + (int256 signedCoefficient, int256 exponent) = + LibDecimalFloatImplementation.add(signedCoefficientA, exponentA, signedCoefficientB, exponentB); + assertEq(signedCoefficient, expectedSignedCoefficient, "signed coefficient mismatch"); + assertEq(exponent, expectedExponent, "exponent mismatch"); + } + /// Simple 0 add 0 /// 0 + 0 = 0 function testAddZero() external pure { @@ -45,32 +59,32 @@ contract LibDecimalFloatImplementationAddTest is Test { /// 1 add 1 /// 1 + 1 = 2 - function testAddOneOneNotNormalized() external pure { + function testAddOneOneNotMaximized() external pure { (int256 signedCoefficient, int256 exponent) = LibDecimalFloatImplementation.add(1, 0, 1, 0); - assertEq(signedCoefficient, 2e37); - assertEq(exponent, -37); + assertEq(signedCoefficient, 2e75, "Signed coefficient mismatch"); + assertEq(exponent, -75, "Exponent mismatch"); } - function testAddOneOnePreNormalized() external pure { - (int256 signedCoefficient, int256 exponent) = LibDecimalFloatImplementation.add(1e37, -37, 1e37, -37); - assertEq(signedCoefficient, 2e37); - assertEq(exponent, -37); + function testAddOneOnePreMaximized() external pure { + (int256 signedCoefficient, int256 exponent) = LibDecimalFloatImplementation.add(1e75, -75, 1e75, -75); + assertEq(signedCoefficient, 2e75); + assertEq(exponent, -75); } /// 123456789 add 987654321 /// 123456789 + 987654321 = 1111111110 function testAdd123456789987654321() external pure { (int256 signedCoefficient, int256 exponent) = LibDecimalFloatImplementation.add(123456789, 0, 987654321, 0); - assertEq(signedCoefficient, 1.11111111e38); - assertEq(exponent, -38 + 9); + assertEq(signedCoefficient, 1.11111111e76); + assertEq(exponent, -76 + 9); } /// 123456789e9 add 987654321 /// 123456789e9 + 987654321 = 123456789987654321 function testAdd123456789e9987654321() external pure { (int256 signedCoefficient, int256 exponent) = LibDecimalFloatImplementation.add(123456789, 9, 987654321, 0); - assertEq(signedCoefficient, 1.23456789987654321e46); - assertEq(exponent, -46 + 17); + assertEq(signedCoefficient, 1.23456789987654321e75); + assertEq(exponent, -75 + 17); } function testGasAddZero() external pure { @@ -108,9 +122,9 @@ contract LibDecimalFloatImplementationAddTest is Test { vm.assume(signedCoefficientB != 0); (int256 normalizedSignedCoefficientA, int256 normalizedExponentA) = - LibDecimalFloatImplementation.normalize(signedCoefficientA, exponentA); + LibDecimalFloatImplementation.maximize(signedCoefficientA, exponentA); (int256 expectedSignedCoefficient, int256 expectedExponent) = - LibDecimalFloatImplementation.normalize(signedCoefficientB, exponentB); + LibDecimalFloatImplementation.maximize(signedCoefficientB, exponentB); vm.assume(normalizedSignedCoefficientA != 0); vm.assume(expectedSignedCoefficient != 0); @@ -124,57 +138,59 @@ contract LibDecimalFloatImplementationAddTest is Test { } function testAddingSmallToLargeReturnsLargeExamples() external pure { - // Establish a baseline. - (int256 signedCoefficient, int256 exponent) = LibDecimalFloatImplementation.add(1e37, 0, 1e37, -37); - assertEq(signedCoefficient, 10000000000000000000000000000000000001e37); - assertEq(exponent, -37); + // // Establish a baseline. + checkAdd(1e37, 0, 1e37, -37, 10000000000000000000000000000000000001e38, -38); // Show baseline with reversed order. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(1e37, -37, 1e37, 0); - assertEq(signedCoefficient, 10000000000000000000000000000000000001e37); - assertEq(exponent, -37); + checkAdd(1e37, -37, 1e37, 0, 10000000000000000000000000000000000001e38, -38); // Show full precision loss. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(1e37, 0, 1e37, -38); - assertEq(signedCoefficient, 1e37); - assertEq(exponent, 0); + checkAdd(1e37, 0, 1e37, -38, 100000000000000000000000000000000000001e37, -38); + checkAdd(1e37, 0, 1e37, -75, 1000000000000000000000000000000000000000000000000000000000000000000000000001, -38); + checkAdd(1e37, 0, 1e37, -76, 1e75, -38); // Show same thing again with reversed order. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(1e37, -38, 1e37, 0); - assertEq(signedCoefficient, 1e37); - assertEq(exponent, 0); + checkAdd(1e37, -38, 1e37, 0, 100000000000000000000000000000000000001e37, -38); + checkAdd(1e37, -75, 1e37, 0, 1000000000000000000000000000000000000000000000000000000000000000000000000001, -38); + checkAdd(1e37, -76, 1e37, 0, 1e75, -38); // Same precision loss happens for negative numbers. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(-1e37, 0, -1e37, -38); - assertEq(signedCoefficient, -1e37); - assertEq(exponent, 0); + checkAdd(-1e37, 0, -1e37, -38, -100000000000000000000000000000000000001e37, -38); + checkAdd( + -1e37, 0, -1e37, -75, -1000000000000000000000000000000000000000000000000000000000000000000000000001, -38 + ); + checkAdd(-1e37, 0, -1e37, -76, -1e75, -38); // Reverse order. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(-1e37, -38, -1e37, 0); - assertEq(signedCoefficient, -1e37); - assertEq(exponent, 0); + checkAdd(-1e37, -38, -1e37, 0, -100000000000000000000000000000000000001e37, -38); + checkAdd( + -1e37, -75, -1e37, 0, -1000000000000000000000000000000000000000000000000000000000000000000000000001, -38 + ); + checkAdd(-1e37, -76, -1e37, 0, -1e75, -38); // Only the difference in exponents matters. Show the baseline. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(1e37, -20, 1e37, -57); - assertEq(signedCoefficient, 10000000000000000000000000000000000001e37); - assertEq(exponent, -57); - // Reverse order. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(1e37, -57, 1e37, -20); - assertEq(signedCoefficient, 10000000000000000000000000000000000001e37); - assertEq(exponent, -57); - - // Only the difference in exponents matters. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(1e37, -20, 1e37, -58); - assertEq(signedCoefficient, 1e37); - assertEq(exponent, -20); + checkAdd(1e37, -20, 1e37, -57, 10000000000000000000000000000000000001e38, -58); + checkAdd( + 1e37, -20, 1e37, -95, 1000000000000000000000000000000000000000000000000000000000000000000000000001, -58 + ); + checkAdd(1e37, -20, 1e37, -96, 1e75, -58); // Reverse order. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(1e37, -58, 1e37, -20); - assertEq(signedCoefficient, 1e37); + checkAdd(1e37, -57, 1e37, -20, 10000000000000000000000000000000000001e38, -58); + checkAdd( + 1e37, -95, 1e37, -20, 1000000000000000000000000000000000000000000000000000000000000000000000000001, -58 + ); + checkAdd(1e37, -96, 1e37, -20, 1e75, -58); + + // Show the same thing with negative numbers. + checkAdd(-1e37, -20, -1e37, -57, -10000000000000000000000000000000000001e38, -58); + checkAdd( + -1e37, -20, -1e37, -95, -1000000000000000000000000000000000000000000000000000000000000000000000000001, -58 + ); + checkAdd(-1e37, -20, -1e37, -96, -1e75, -58); - // Only the difference in exponents matters. Show negative numbers. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(-1e37, -20, -1e37, -58); - assertEq(signedCoefficient, -1e37); - assertEq(exponent, -20); // Reverse order. - (signedCoefficient, exponent) = LibDecimalFloatImplementation.add(-1e37, -58, -1e37, -20); - assertEq(signedCoefficient, -1e37); + checkAdd(-1e37, -57, -1e37, -20, -10000000000000000000000000000000000001e38, -58); + checkAdd( + -1e37, -95, -1e37, -20, -1000000000000000000000000000000000000000000000000000000000000000000000000001, -58 + ); + checkAdd(-1e37, -96, -1e37, -20, -1e75, -58); } /// If the exponents are the same and the coefficients are the same, then @@ -182,22 +198,25 @@ contract LibDecimalFloatImplementationAddTest is Test { function testAddSameExponentSameCoefficient(int256 signedCoefficientA, int256 signedCoefficientB) external pure { int256 exponentA; int256 exponentB; - (signedCoefficientA, exponentA) = LibDecimalFloatImplementation.normalize(signedCoefficientA, 0); - (signedCoefficientB, exponentB) = LibDecimalFloatImplementation.normalize(signedCoefficientB, 0); + int256 signedCoefficientAMaximized; + int256 signedCoefficientBMaximized; + (signedCoefficientAMaximized, exponentA) = LibDecimalFloatImplementation.maximize(signedCoefficientA, 0); + (signedCoefficientBMaximized, exponentB) = LibDecimalFloatImplementation.maximize(signedCoefficientB, 0); if (signedCoefficientA == 0 || signedCoefficientB == 0) { exponentA = 0; } exponentB = exponentA; - (int256 signedCoefficient, int256 exponent) = - LibDecimalFloatImplementation.add(signedCoefficientA, exponentA, signedCoefficientB, exponentB); - - int256 expectedSignedCoefficient = signedCoefficientA + signedCoefficientB; + int256 expectedSignedCoefficient = signedCoefficientAMaximized + signedCoefficientBMaximized; int256 expectedExponent = exponentA; - assertEq(signedCoefficient, expectedSignedCoefficient); - assertEq(exponent, expectedExponent); + (int256 signedCoefficient, int256 exponent) = LibDecimalFloatImplementation.add( + signedCoefficientAMaximized, exponentA, signedCoefficientBMaximized, exponentB + ); + + assertEq(signedCoefficient, expectedSignedCoefficient, "signed coefficient mismatch"); + assertEq(exponent, expectedExponent, "exponent mismatch"); } /// Adding any zero to any value returns the non-zero value. diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.log10.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.log10.t.sol index e09ee0e0..570c57da 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.log10.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.log10.t.sol @@ -30,20 +30,20 @@ contract LibDecimalFloatImplementationLog10Test is LogTest { checkLog10(1e37, -37, 0, 0); } - function testExactLookups() external { - checkLog10(1001, 0, 3.0004e41, -41); - checkLog10(100.1e1, -1, 2.0004e41, -41); - checkLog10(10.01e2, -2, 1.0004e41, -41); + function testExactLookupsLog10() external { + checkLog10(1001, 0, 3.0004e75, -75); + checkLog10(100.1e1, -1, 2.0004e75, -75); + checkLog10(10.01e2, -2, 1.0004e75, -75); checkLog10(1.001e3, -3, 0.0004e38, -38); - checkLog10(10.02e2, -2, 1.0009e41, -41); - checkLog10(10.99e2, -2, 1.0411e39, -39); + checkLog10(10.02e2, -2, 1.0009e75, -75); + checkLog10(10.99e2, -2, 1.0411e75, -75); - checkLog10(6566, 0, 3.8173e38, -38); + checkLog10(6566, 0, 3.8173e75, -75); } function testInterpolatedLookups() external { - checkLog10(10.015e3, -3, 1.00065e41, -41); + checkLog10(10.015e3, -3, 1.00065e75, -75); } function testSub1() external { diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.pow10.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.pow10.t.sol index fbc14173..ae11d4b5 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.pow10.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.pow10.t.sol @@ -61,11 +61,16 @@ contract LibDecimalFloatImplementationPow10Test is LogTest { function testInterpolatedLookupsPower() external { // 10^1.55555 = 35.9376769153 - checkPow10(1.55555e37, -37, 35935e37, -40); + checkPow10(1.55555e37, -37, 35935e71, -74); // 10^1234.56789 - checkPow10(123456789, -5, 36979e37, 1193); + checkPow10(123456789, -5, 36979e71, 1159); // ~= 10 (fuzzing found this edge case). - checkPow10(99999999999999999999999999999999999997448, -41, 99999999999999999999999999999999999991000, -40); + checkPow10( + 99999999999999999999999999999999999997448, + -41, + 9999999999999999999999999999999999999234400000000000000000000000000000000000, + -75 + ); } function boundFloat(int224 x, int32 exponent) internal pure returns (int224, int32) { From df8ad843e658a6a889e62cec9b4ee8447931d905 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 16:59:32 +0400 Subject: [PATCH 02/14] maximize --- .../LibDecimalFloatImplementation.sol | 7 +- ...bDecimalFloatImplementation.maximize.t.sol | 65 +++++++++++++++++++ 2 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 test/src/lib/implementation/LibDecimalFloatImplementation.maximize.t.sol diff --git a/src/lib/implementation/LibDecimalFloatImplementation.sol b/src/lib/implementation/LibDecimalFloatImplementation.sol index 562179bc..ad73dc10 100644 --- a/src/lib/implementation/LibDecimalFloatImplementation.sol +++ b/src/lib/implementation/LibDecimalFloatImplementation.sol @@ -539,10 +539,11 @@ library LibDecimalFloatImplementation { if (exponent < initialExponent) { revert ExponentOverflow(signedCoefficient, exponent); } - } else { + } + // Check if already maximized before dropping into a block full of + // jumps. + else if (signedCoefficient / 1e75 == 0) { while (signedCoefficient / 1e75 == 0) { - // This is a "jump down" in the exponent, so we can multiply - // the coefficient by 10 and decrease the exponent by 1. signedCoefficient *= 10; exponent -= 1; } diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.maximize.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.maximize.t.sol new file mode 100644 index 00000000..79d31165 --- /dev/null +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.maximize.t.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +import {Test} from "forge-std/Test.sol"; + +import { + LibDecimalFloatImplementation, + EXPONENT_MIN, + EXPONENT_MAX, + MAXIMIZED_ZERO_EXPONENT, + MAXIMIZED_ZERO_SIGNED_COEFFICIENT +} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; + +contract LibDecimalFloatImplementationMaximizeTest is Test { + function isMaximized(int256 signedCoefficient, int256 exponent) internal pure returns (bool) { + if (signedCoefficient == 0) { + return exponent == MAXIMIZED_ZERO_EXPONENT && signedCoefficient == MAXIMIZED_ZERO_SIGNED_COEFFICIENT; + } + + if (signedCoefficient / 1e76 != 0) { + return false; + } + + if (signedCoefficient / 1e75 == 0) { + return false; + } + + return true; + } + + /// Every normalized number is maximized. + function testMaximized(int256 signedCoefficient, int256 exponent) external pure { + exponent = bound(exponent, EXPONENT_MIN, EXPONENT_MAX); + (int256 actualSignedCoefficient, int256 actualExponent) = + LibDecimalFloatImplementation.maximize(signedCoefficient, exponent); + assertTrue(isMaximized(actualSignedCoefficient, actualExponent)); + } + + function checkMaximized( + int256 signedCoefficient, + int256 exponent, + int256 expectedCoefficient, + int256 expectedExponent + ) internal pure { + (int256 actualSignedCoefficient, int256 actualExponent) = + LibDecimalFloatImplementation.maximize(signedCoefficient, exponent); + assertEq(actualSignedCoefficient, expectedCoefficient); + assertEq(actualExponent, expectedExponent); + } + + function testMaximizedExamples() external pure { + checkMaximized(0, 0, 0, 0); + checkMaximized(0, 1, 0, 0); + checkMaximized(1e37, 0, 1e75, -38); + checkMaximized(1e75, 0, 1e75, 0); + checkMaximized(type(int256).max, 0, type(int256).max / 10, 1); + checkMaximized(type(int256).min, 0, type(int256).min / 10, 1); + checkMaximized(42, 0, 42e74, -74); + checkMaximized(42e74, -74, 42e74, -74); + + for (int256 i = 76; i >= 0; i--) { + checkMaximized(int256(10 ** uint256(i)), 0, 1e75, i - 75); + } + } +} From aeebef0385ba13bef7d07e18f000a2ff5da36303 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 17:20:05 +0400 Subject: [PATCH 03/14] maximize optimize --- .../LibDecimalFloatImplementation.sol | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/lib/implementation/LibDecimalFloatImplementation.sol b/src/lib/implementation/LibDecimalFloatImplementation.sol index ad73dc10..1e69af3c 100644 --- a/src/lib/implementation/LibDecimalFloatImplementation.sol +++ b/src/lib/implementation/LibDecimalFloatImplementation.sol @@ -543,7 +543,27 @@ library LibDecimalFloatImplementation { // Check if already maximized before dropping into a block full of // jumps. else if (signedCoefficient / 1e75 == 0) { - while (signedCoefficient / 1e75 == 0) { + if (signedCoefficient / 1e38 == 0) { + signedCoefficient *= 1e38; + exponent -= 38; + } + + if (signedCoefficient / 1e57 == 0) { + signedCoefficient *= 1e19; + exponent -= 19; + } + + if (signedCoefficient / 1e66 == 0) { + signedCoefficient *= 1e10; + exponent -= 10; + } + + while (signedCoefficient / 1e74 == 0) { + signedCoefficient *= 1e2; + exponent -= 2; + } + + if (signedCoefficient / 1e75 == 0) { signedCoefficient *= 10; exponent -= 1; } From b006e6c980b415cdad819d2b58a7d8e0854375e0 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 17:21:56 +0400 Subject: [PATCH 04/14] idempotent maximized --- .../LibDecimalFloatImplementation.maximize.t.sol | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.maximize.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.maximize.t.sol index 79d31165..3ce7fcdc 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.maximize.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.maximize.t.sol @@ -62,4 +62,15 @@ contract LibDecimalFloatImplementationMaximizeTest is Test { checkMaximized(int256(10 ** uint256(i)), 0, 1e75, i - 75); } } + + /// Maximization should be idempotent. + function testMaximizedIdempotent(int256 signedCoefficient, int256 exponent) external pure { + exponent = bound(exponent, EXPONENT_MIN, EXPONENT_MAX); + (int256 maximizedSignedCoefficient, int256 maximizedExponent) = + LibDecimalFloatImplementation.maximize(signedCoefficient, exponent); + (int256 actualSignedCoefficient, int256 actualExponent) = + LibDecimalFloatImplementation.maximize(maximizedSignedCoefficient, maximizedExponent); + assertEq(actualSignedCoefficient, maximizedSignedCoefficient); + assertEq(actualExponent, maximizedExponent); + } } From 91d8a775efad06f47bf54e9d11cea020beb44783 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 18:21:33 +0400 Subject: [PATCH 05/14] ceil --- src/lib/LibDecimalFloat.sol | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/lib/LibDecimalFloat.sol b/src/lib/LibDecimalFloat.sol index 525971a0..e5681ff9 100644 --- a/src/lib/LibDecimalFloat.sol +++ b/src/lib/LibDecimalFloat.sol @@ -634,12 +634,25 @@ library LibDecimalFloat { } (int256 characteristic, int256 mantissa) = LibDecimalFloatImplementation.characteristicMantissa(signedCoefficient, exponent); + + // If the mantissa is 0, then the float is already an integer. + // No need to repack or other checks. + if (mantissa == 0) { + return float; + } + (Float result, bool lossless) = packLossy(characteristic, exponent); + (lossless); + + // If the mantissa is less then zero then the ceil is the characteristic. + // This is because the mantissa is making the original value smaller, so + // dropping it makes the value larger. + // We only add one if the mantissa is greater than zero. In this case, + // when we drop the mantissa the value becomes smaller so we have to add + // one to the characteristic to get the ceil. if (mantissa > 0) { result = add(result, FLOAT_ONE); } - // Ceiling is lossy by definition. - (lossless, mantissa); return result; } From 66fbd06ba6cf17579f6af5c3b22963682752e447 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 18:27:30 +0400 Subject: [PATCH 06/14] lint --- .gas-snapshot | 369 ++++++++++++------------ test/src/lib/LibDecimalFloat.ceil.t.sol | 18 +- 2 files changed, 197 insertions(+), 190 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 00245815..18725d40 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,145 +1,145 @@ -DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5108, μ: 2492261, ~: 2492203) -DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5108, μ: 2503699, ~: 2496973) -DecimalFloatConstantsTest:testEDeployed() (gas: 2491468) -DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2491500) -DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2491436) -DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2491411) -DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2491390) -DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5108, μ: 2494759, ~: 2494616) -DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5108, μ: 2492668, ~: 2492593) -DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5108, μ: 2492121, ~: 2491936) -DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5108, μ: 2496271, ~: 2496107) -DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5108, μ: 2492512, ~: 2492496) -DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5108, μ: 2493068, ~: 2493000) -DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5108, μ: 2493557, ~: 2493470) -DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5108, μ: 2492588, ~: 2492513) -DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5108, μ: 2492661, ~: 2492586) -DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5108, μ: 2493853, ~: 2493776) -DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5108, μ: 2491778, ~: 2491778) -DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5108, μ: 2492565, ~: 2492490) -DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5108, μ: 2492618, ~: 2492543) -DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5108, μ: 2492649, ~: 2492587) -DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5108, μ: 2492646, ~: 2492585) -DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5108, μ: 2492338, ~: 2492338) -DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5108, μ: 2494551, ~: 2495610) -DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5108, μ: 158769, ~: 158769) -DecimalFloatParseTest:testParseDeployed(string) (runs: 5108, μ: 2495080, ~: 2494950) -DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5108, μ: 2511030, ~: 2500616) -DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5108, μ: 2509995, ~: 2501330) -DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5108, μ: 2503984, ~: 2497305) -DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5108, μ: 2493686, ~: 2493583) -DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5108, μ: 2493832, ~: 2494112) -LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5107, μ: 5121, ~: 5121) -LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5108, μ: 10475, ~: 10702) -LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5108, μ: 9641, ~: 9392) -LibDecimalFloatCeilTest:testCeilExamples() (gas: 118610) -LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5108, μ: 12359, ~: 11055) -LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5108, μ: 9944, ~: 9807) -LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5108, μ: 8955, ~: 9216) -LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5108, μ: 583, ~: 411) -LibDecimalFloatCeilTest:testCeilZero(int32) (runs: 5108, μ: 5438, ~: 5438) +DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5109, μ: 2544181, ~: 2544123) +DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5109, μ: 2548014, ~: 2548093) +DecimalFloatConstantsTest:testEDeployed() (gas: 2543388) +DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2543420) +DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2543356) +DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2543331) +DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2543310) +DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5109, μ: 2546680, ~: 2546536) +DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5109, μ: 2544589, ~: 2544513) +DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5109, μ: 2544041, ~: 2543856) +DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5109, μ: 2548169, ~: 2547999) +DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5109, μ: 2544433, ~: 2544416) +DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5109, μ: 2544988, ~: 2544920) +DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5109, μ: 2545476, ~: 2545390) +DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5109, μ: 2544508, ~: 2544433) +DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5109, μ: 2544582, ~: 2544506) +DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5109, μ: 2545771, ~: 2545696) +DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5109, μ: 2543698, ~: 2543698) +DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5109, μ: 2544486, ~: 2544410) +DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5109, μ: 2544538, ~: 2544463) +DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5109, μ: 2544569, ~: 2544507) +DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5109, μ: 2544567, ~: 2544505) +DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5109, μ: 2544258, ~: 2544258) +DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5109, μ: 2546471, ~: 2547530) +DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5109, μ: 158769, ~: 158769) +DecimalFloatParseTest:testParseDeployed(string) (runs: 5109, μ: 2547000, ~: 2546870) +DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5109, μ: 2555311, ~: 2552536) +DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5109, μ: 2554549, ~: 2553250) +DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5109, μ: 2548323, ~: 2548397) +DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5109, μ: 2545614, ~: 2545503) +DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5109, μ: 2545751, ~: 2546032) +LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5108, μ: 5121, ~: 5121) +LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5109, μ: 10475, ~: 10702) +LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5109, μ: 9641, ~: 9392) +LibDecimalFloatCeilTest:testCeilExamples() (gas: 35882) +LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5109, μ: 11439, ~: 11078) +LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5109, μ: 9965, ~: 9830) +LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5109, μ: 8966, ~: 9216) +LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5109, μ: 592, ~: 411) +LibDecimalFloatCeilTest:testCeilZero(int32) (runs: 5109, μ: 5438, ~: 5438) LibDecimalFloatConstantsTest:testFloatE() (gas: 3357) LibDecimalFloatConstantsTest:testFloatHalf() (gas: 3336) LibDecimalFloatConstantsTest:testFloatMaxNegativeValue() (gas: 3379) -LibDecimalFloatConstantsTest:testFloatMaxNegativeValueIsMax(bytes32) (runs: 5108, μ: 4488, ~: 4594) +LibDecimalFloatConstantsTest:testFloatMaxNegativeValueIsMax(bytes32) (runs: 5109, μ: 4488, ~: 4594) LibDecimalFloatConstantsTest:testFloatMaxPositiveValue() (gas: 3335) -LibDecimalFloatConstantsTest:testFloatMaxPositiveValueIsMax(bytes32) (runs: 5108, μ: 3545, ~: 3586) +LibDecimalFloatConstantsTest:testFloatMaxPositiveValueIsMax(bytes32) (runs: 5109, μ: 3545, ~: 3586) LibDecimalFloatConstantsTest:testFloatMinNegativeValue() (gas: 3335) -LibDecimalFloatConstantsTest:testFloatMinNegativeValueIsMin(bytes32) (runs: 5108, μ: 3496, ~: 3457) +LibDecimalFloatConstantsTest:testFloatMinNegativeValueIsMin(bytes32) (runs: 5109, μ: 3496, ~: 3457) LibDecimalFloatConstantsTest:testFloatMinPositiveValue() (gas: 3357) -LibDecimalFloatConstantsTest:testFloatMinPositiveValueIsMin(bytes32) (runs: 5108, μ: 4938, ~: 4870) +LibDecimalFloatConstantsTest:testFloatMinPositiveValueIsMin(bytes32) (runs: 5109, μ: 4938, ~: 4870) LibDecimalFloatConstantsTest:testFloatOne() (gas: 3358) LibDecimalFloatConstantsTest:testFloatTwo() (gas: 3380) LibDecimalFloatConstantsTest:testFloatZero() (gas: 3337) -LibDecimalFloatDecimalAddTest:testAddPacked(bytes32,bytes32) (runs: 5108, μ: 16977, ~: 10308) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5103, μ: 9615, ~: 9663) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5108, μ: 8130, ~: 8048) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5108, μ: 7452, ~: 7424) +LibDecimalFloatDecimalAddTest:testAddPacked(bytes32,bytes32) (runs: 5109, μ: 9467, ~: 9568) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5104, μ: 9615, ~: 9663) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5109, μ: 8130, ~: 8048) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5109, μ: 7452, ~: 7424) LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessFail() (gas: 4894) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPacked(bytes32,uint8) (runs: 5108, μ: 6718, ~: 6161) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5108, μ: 15805, ~: 15768) -LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5108, μ: 9274, ~: 9053) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPacked(bytes32,uint8) (runs: 5109, μ: 6719, ~: 6161) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5109, μ: 15805, ~: 15768) +LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5109, μ: 9274, ~: 9053) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyComplicated() (gas: 685958) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMax() (gas: 673506) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMaxPlusOne() (gas: 704362) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOne() (gas: 685936) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOneMillion() (gas: 685937) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOverflow() (gas: 715261) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyPacked(uint256,uint8) (runs: 5108, μ: 9460, ~: 9374) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5108, μ: 5978, ~: 5937) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5108, μ: 7306, ~: 5860) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyPacked(uint256,uint8) (runs: 5109, μ: 9460, ~: 9374) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5109, μ: 5978, ~: 5937) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5109, μ: 7306, ~: 5860) LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5101, μ: 16005, ~: 15996) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5108, μ: 14964, ~: 14729) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5108, μ: 10151, ~: 9811) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5108, μ: 10825, ~: 11076) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyPacked(bytes32,uint8) (runs: 5108, μ: 6805, ~: 6905) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5103, μ: 15348, ~: 15612) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5108, μ: 14493, ~: 14212) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5109, μ: 14964, ~: 14729) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5109, μ: 10151, ~: 9811) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5109, μ: 10825, ~: 11076) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyPacked(bytes32,uint8) (runs: 5109, μ: 6805, ~: 6905) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5104, μ: 15348, ~: 15612) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5109, μ: 14493, ~: 14212) LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncateLossless() (gas: 14523) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5108, μ: 13739, ~: 13602) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5108, μ: 4598, ~: 4598) -LibDecimalFloatDivTest:testDivPacked(bytes32,bytes32) (runs: 5108, μ: 8052, ~: 7855) -LibDecimalFloatEqTest:testEqPacked(bytes32,bytes32) (runs: 5108, μ: 5524, ~: 5450) -LibDecimalFloatEqTest:testEqXNotYExponents(bytes32,bytes32) (runs: 5108, μ: 4341, ~: 4234) -LibDecimalFloatEqTest:testEqZero(int32) (runs: 5108, μ: 5133, ~: 5133) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5109, μ: 13739, ~: 13602) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5109, μ: 4598, ~: 4598) +LibDecimalFloatDivTest:testDivPacked(bytes32,bytes32) (runs: 5109, μ: 8052, ~: 7855) +LibDecimalFloatEqTest:testEqPacked(bytes32,bytes32) (runs: 5109, μ: 5524, ~: 5450) +LibDecimalFloatEqTest:testEqXNotYExponents(bytes32,bytes32) (runs: 5109, μ: 4341, ~: 4234) +LibDecimalFloatEqTest:testEqZero(int32) (runs: 5109, μ: 5133, ~: 5133) LibDecimalFloatFloorTest:testFloorExamples() (gas: 38387) LibDecimalFloatFloorTest:testFloorGas0() (gas: 960) LibDecimalFloatFloorTest:testFloorGasTiny() (gas: 881) LibDecimalFloatFloorTest:testFloorGasZero() (gas: 553) -LibDecimalFloatFloorTest:testFloorInRange(int224,int256) (runs: 5108, μ: 11032, ~: 11044) -LibDecimalFloatFloorTest:testFloorLessThanMin(int224,int256) (runs: 5108, μ: 10284, ~: 10293) -LibDecimalFloatFloorTest:testFloorNonNegative(int224,int256) (runs: 5108, μ: 9547, ~: 9806) -LibDecimalFloatFloorTest:testFloorNotReverts(bytes32) (runs: 5108, μ: 461, ~: 365) +LibDecimalFloatFloorTest:testFloorInRange(int224,int256) (runs: 5109, μ: 11032, ~: 11044) +LibDecimalFloatFloorTest:testFloorLessThanMin(int224,int256) (runs: 5109, μ: 10284, ~: 10293) +LibDecimalFloatFloorTest:testFloorNonNegative(int224,int256) (runs: 5109, μ: 9547, ~: 9806) +LibDecimalFloatFloorTest:testFloorNotReverts(bytes32) (runs: 5109, μ: 461, ~: 365) LibDecimalFloatFracTest:testFracExamples() (gas: 39135) LibDecimalFloatFracTest:testFracGas0() (gas: 960) LibDecimalFloatFracTest:testFracGasTiny() (gas: 836) LibDecimalFloatFracTest:testFracGasZero() (gas: 820) -LibDecimalFloatFracTest:testFracInRange(int224,int256) (runs: 5108, μ: 10847, ~: 10859) -LibDecimalFloatFracTest:testFracLessThanMin(int224,int256) (runs: 5108, μ: 10273, ~: 10280) -LibDecimalFloatFracTest:testFracNonNegative(int224,int256) (runs: 5108, μ: 9806, ~: 10066) -LibDecimalFloatFracTest:testFracNotReverts(bytes32) (runs: 5108, μ: 630, ~: 621) +LibDecimalFloatFracTest:testFracInRange(int224,int256) (runs: 5109, μ: 10847, ~: 10859) +LibDecimalFloatFracTest:testFracLessThanMin(int224,int256) (runs: 5109, μ: 10273, ~: 10280) +LibDecimalFloatFracTest:testFracNonNegative(int224,int256) (runs: 5109, μ: 9806, ~: 10066) +LibDecimalFloatFracTest:testFracNotReverts(bytes32) (runs: 5109, μ: 630, ~: 621) LibDecimalFloatGtTest:testGtGasAZero() (gas: 973) LibDecimalFloatGtTest:testGtGasBZero() (gas: 973) LibDecimalFloatGtTest:testGtGasBothZero() (gas: 751) LibDecimalFloatGtTest:testGtGasDifferentSigns() (gas: 974) LibDecimalFloatGtTest:testGtGasExponentDiffOverflow() (gas: 1143) -LibDecimalFloatGtTest:testGtOneEAny(bytes32) (runs: 5108, μ: 3494, ~: 3494) -LibDecimalFloatGtTest:testGtReference(int224,int32,int224,int32) (runs: 5108, μ: 8064, ~: 6272) -LibDecimalFloatGtTest:testGtX(int224,int32) (runs: 5108, μ: 3882, ~: 3882) -LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int32,int32) (runs: 5108, μ: 10593, ~: 10332) -LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5108, μ: 11144, ~: 11349) -LibDecimalFloatGtTest:testGtXNotY(bytes32,bytes32) (runs: 5108, μ: 4341, ~: 4232) -LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int32,int256,int32) (runs: 5108, μ: 13764, ~: 13595) -LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int32,int32) (runs: 5108, μ: 10274, ~: 10026) -LibDecimalFloatGtTest:testGtZero(int32,int32) (runs: 5108, μ: 4793, ~: 4793) +LibDecimalFloatGtTest:testGtOneEAny(bytes32) (runs: 5109, μ: 3494, ~: 3494) +LibDecimalFloatGtTest:testGtReference(int224,int32,int224,int32) (runs: 5109, μ: 8064, ~: 6272) +LibDecimalFloatGtTest:testGtX(int224,int32) (runs: 5109, μ: 3882, ~: 3882) +LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int32,int32) (runs: 5109, μ: 10593, ~: 10332) +LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5109, μ: 11144, ~: 11349) +LibDecimalFloatGtTest:testGtXNotY(bytes32,bytes32) (runs: 5109, μ: 4341, ~: 4232) +LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int32,int256,int32) (runs: 5109, μ: 13764, ~: 13595) +LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int32,int32) (runs: 5109, μ: 10274, ~: 10026) +LibDecimalFloatGtTest:testGtZero(int32,int32) (runs: 5109, μ: 4793, ~: 4793) LibDecimalFloatGteTest:testGteGasAZero() (gas: 976) LibDecimalFloatGteTest:testGteGasBZero() (gas: 1020) LibDecimalFloatGteTest:testGteGasBothZero() (gas: 753) LibDecimalFloatGteTest:testGteGasDifferentSigns() (gas: 996) LibDecimalFloatGteTest:testGteGasExponentDiffOverflow() (gas: 1102) -LibDecimalFloatGteTest:testGteOneEAny(bytes32) (runs: 5108, μ: 3494, ~: 3494) -LibDecimalFloatGteTest:testGteReference(int224,int32,int224,int32) (runs: 5108, μ: 8114, ~: 6344) -LibDecimalFloatGteTest:testGteX(int224,int32) (runs: 5108, μ: 3925, ~: 3925) -LibDecimalFloatGteTest:testGteXEAnyVsXEAny(int256,int32,int32) (runs: 5108, μ: 10622, ~: 10364) -LibDecimalFloatGteTest:testGteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5108, μ: 11156, ~: 11361) -LibDecimalFloatGteTest:testGteXNotLtY(bytes32,bytes32) (runs: 5108, μ: 3947, ~: 3873) -LibDecimalFloatGteTest:testGteXPositiveYNegative(int256,int32,int256,int32) (runs: 5108, μ: 13794, ~: 13623) -LibDecimalFloatGteTest:testGteXPositiveYZero(int256,int32,int32) (runs: 5108, μ: 9551, ~: 9170) -LibDecimalFloatGteTest:testGteZero(int32,int32) (runs: 5108, μ: 4838, ~: 4838) -LibDecimalFloatImplementationAddTest:testAdd123456789987654321() (gas: 13762) -LibDecimalFloatImplementationAddTest:testAdd123456789e9987654321() (gas: 13814) -LibDecimalFloatImplementationAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5108, μ: 19288, ~: 19407) -LibDecimalFloatImplementationAddTest:testAddOneOneNotMaximized() (gas: 15721) -LibDecimalFloatImplementationAddTest:testAddOneOnePreMaximized() (gas: 4181) +LibDecimalFloatGteTest:testGteOneEAny(bytes32) (runs: 5109, μ: 3494, ~: 3494) +LibDecimalFloatGteTest:testGteReference(int224,int32,int224,int32) (runs: 5109, μ: 8114, ~: 6344) +LibDecimalFloatGteTest:testGteX(int224,int32) (runs: 5109, μ: 3925, ~: 3925) +LibDecimalFloatGteTest:testGteXEAnyVsXEAny(int256,int32,int32) (runs: 5109, μ: 10622, ~: 10364) +LibDecimalFloatGteTest:testGteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5109, μ: 11156, ~: 11361) +LibDecimalFloatGteTest:testGteXNotLtY(bytes32,bytes32) (runs: 5109, μ: 3947, ~: 3873) +LibDecimalFloatGteTest:testGteXPositiveYNegative(int256,int32,int256,int32) (runs: 5109, μ: 13794, ~: 13623) +LibDecimalFloatGteTest:testGteXPositiveYZero(int256,int32,int32) (runs: 5109, μ: 9551, ~: 9170) +LibDecimalFloatGteTest:testGteZero(int32,int32) (runs: 5109, μ: 4838, ~: 4838) +LibDecimalFloatImplementationAddTest:testAdd123456789987654321() (gas: 4602) +LibDecimalFloatImplementationAddTest:testAdd123456789e9987654321() (gas: 4654) +LibDecimalFloatImplementationAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5109, μ: 13048, ~: 12978) +LibDecimalFloatImplementationAddTest:testAddOneOneNotMaximized() (gas: 5985) +LibDecimalFloatImplementationAddTest:testAddOneOnePreMaximized() (gas: 4129) LibDecimalFloatImplementationAddTest:testAddOneZero() (gas: 3666) -LibDecimalFloatImplementationAddTest:testAddSameExponentSameCoefficient(int256,int256) (runs: 5108, μ: 12503, ~: 12450) +LibDecimalFloatImplementationAddTest:testAddSameExponentSameCoefficient(int256,int256) (runs: 5109, μ: 6265, ~: 6334) LibDecimalFloatImplementationAddTest:testAddZero() (gas: 3687) -LibDecimalFloatImplementationAddTest:testAddZeroAnyExponent(int128) (runs: 5108, μ: 9293, ~: 9271) +LibDecimalFloatImplementationAddTest:testAddZeroAnyExponent(int128) (runs: 5109, μ: 9294, ~: 9271) LibDecimalFloatImplementationAddTest:testAddZeroOne() (gas: 3664) -LibDecimalFloatImplementationAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5107, μ: 13988, ~: 13961) -LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeExamples() (gas: 204071) -LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5100, μ: 29701, ~: 30074) -LibDecimalFloatImplementationAddTest:testGasAddOne() (gas: 6283) +LibDecimalFloatImplementationAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5108, μ: 13985, ~: 13961) +LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeExamples() (gas: 71367) +LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5099, μ: 16839, ~: 16821) +LibDecimalFloatImplementationAddTest:testGasAddOne() (gas: 1179) LibDecimalFloatImplementationAddTest:testGasAddZero() (gas: 360) LibDecimalFloatImplementationDivTest:testDiv1Over3() (gas: 6014) LibDecimalFloatImplementationDivTest:testDiv1Over3Gas0() (gas: 716) @@ -150,120 +150,123 @@ LibDecimalFloatImplementationDivTest:testDivNegative1Over3() (gas: 6074) LibDecimalFloatImplementationDivTest:testDivOOMs5and2() (gas: 4848) LibDecimalFloatImplementationDivTest:testDivOOMsOverTen() (gas: 5665) LibDecimalFloatImplementationDivTest:testDivTenOverOOMs() (gas: 5590) -LibDecimalFloatImplementationDivTest:testUnnormalizedThreesDiv0(int256,int256) (runs: 112, μ: 21050742, ~: 21050370) +LibDecimalFloatImplementationDivTest:testUnnormalizedThreesDiv0(int256,int256) (runs: 113, μ: 21050750, ~: 21050370) LibDecimalFloatImplementationEqTest:testEqGasAZero() (gas: 430) LibDecimalFloatImplementationEqTest:testEqGasBZero() (gas: 473) LibDecimalFloatImplementationEqTest:testEqGasBothZero() (gas: 450) LibDecimalFloatImplementationEqTest:testEqGasDifferentSigns() (gas: 482) LibDecimalFloatImplementationEqTest:testEqGasExponentDiffOverflow() (gas: 533) -LibDecimalFloatImplementationEqTest:testEqNotReverts(int256,int256,int256,int256) (runs: 5108, μ: 654, ~: 679) -LibDecimalFloatImplementationEqTest:testEqOneEAny(int256,int256) (runs: 5108, μ: 3416, ~: 3416) -LibDecimalFloatImplementationEqTest:testEqReference(int256,int256,int256,int256) (runs: 5108, μ: 9901, ~: 11437) -LibDecimalFloatImplementationEqTest:testEqX(int256) (runs: 5108, μ: 3392, ~: 3392) -LibDecimalFloatImplementationEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5106, μ: 4718, ~: 4714) -LibDecimalFloatImplementationEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5108, μ: 732, ~: 753) -LibDecimalFloatImplementationEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5108, μ: 3928, ~: 3953) -LibDecimalFloatImplementationEqTest:testEqZero(int256,int256) (runs: 5108, μ: 3440, ~: 3440) +LibDecimalFloatImplementationEqTest:testEqNotReverts(int256,int256,int256,int256) (runs: 5109, μ: 654, ~: 679) +LibDecimalFloatImplementationEqTest:testEqOneEAny(int256,int256) (runs: 5109, μ: 3416, ~: 3416) +LibDecimalFloatImplementationEqTest:testEqReference(int256,int256,int256,int256) (runs: 5109, μ: 9901, ~: 11437) +LibDecimalFloatImplementationEqTest:testEqX(int256) (runs: 5109, μ: 3392, ~: 3392) +LibDecimalFloatImplementationEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5107, μ: 4718, ~: 4714) +LibDecimalFloatImplementationEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5109, μ: 732, ~: 753) +LibDecimalFloatImplementationEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5109, μ: 3928, ~: 3953) +LibDecimalFloatImplementationEqTest:testEqZero(int256,int256) (runs: 5109, μ: 3440, ~: 3440) LibDecimalFloatImplementationInvTest:testInvGas0() (gas: 734) -LibDecimalFloatImplementationInvTest:testInvReference(int256,int256) (runs: 5106, μ: 12225, ~: 12163) +LibDecimalFloatImplementationInvTest:testInvReference(int256,int256) (runs: 5107, μ: 12225, ~: 12163) LibDecimalFloatImplementationInvTest:testInvSlowGas0() (gas: 755) LibDecimalFloatImplementationLog10Test:testExactLogs() (gas: 1263178) -LibDecimalFloatImplementationLog10Test:testExactLookupsLog10() (gas: 1324402) -LibDecimalFloatImplementationLog10Test:testInterpolatedLookups() (gas: 1285189) -LibDecimalFloatImplementationLog10Test:testSub1() (gas: 1271435) -LibDecimalFloatImplementationMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5108, μ: 12953, ~: 12929) +LibDecimalFloatImplementationLog10Test:testExactLookupsLog10() (gas: 1279384) +LibDecimalFloatImplementationLog10Test:testInterpolatedLookups() (gas: 1259927) +LibDecimalFloatImplementationLog10Test:testSub1() (gas: 1256123) +LibDecimalFloatImplementationMaximizeTest:testMaximized(int256,int256) (runs: 5109, μ: 9488, ~: 9443) +LibDecimalFloatImplementationMaximizeTest:testMaximizedExamples() (gas: 157696) +LibDecimalFloatImplementationMaximizeTest:testMaximizedIdempotent(int256,int256) (runs: 5109, μ: 9794, ~: 9748) +LibDecimalFloatImplementationMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5109, μ: 12951, ~: 12929) LibDecimalFloatImplementationMulTest:testMul123456789987654321() (gas: 3676) -LibDecimalFloatImplementationMulTest:testMul123456789987654321WithExponents(int128,int128) (runs: 5108, μ: 13185, ~: 13270) +LibDecimalFloatImplementationMulTest:testMul123456789987654321WithExponents(int128,int128) (runs: 5109, μ: 13185, ~: 13270) LibDecimalFloatImplementationMulTest:testMul1e181e19() (gas: 3720) LibDecimalFloatImplementationMulTest:testMulGasOne() (gas: 382) LibDecimalFloatImplementationMulTest:testMulGasZero() (gas: 324) -LibDecimalFloatImplementationMulTest:testMulNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5108, μ: 13394, ~: 12563) +LibDecimalFloatImplementationMulTest:testMulNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5109, μ: 13394, ~: 12563) LibDecimalFloatImplementationMulTest:testMulOneOne() (gas: 3721) LibDecimalFloatImplementationMulTest:testMulOneZero() (gas: 3663) LibDecimalFloatImplementationMulTest:testMulZero0Exponent() (gas: 3620) -LibDecimalFloatImplementationMulTest:testMulZeroAnyExponent(int64,int64) (runs: 5108, μ: 3908, ~: 3908) +LibDecimalFloatImplementationMulTest:testMulZeroAnyExponent(int64,int64) (runs: 5109, μ: 3908, ~: 3908) LibDecimalFloatImplementationMulTest:testMulZeroOne() (gas: 3642) LibDecimalFloatImplementationNormalizeTest:testExamples() (gas: 160899) -LibDecimalFloatImplementationNormalizeTest:testIdempotent(int256,int256) (runs: 5108, μ: 9875, ~: 9808) -LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5108, μ: 3533, ~: 3539) -LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5108, μ: 9415, ~: 9348) +LibDecimalFloatImplementationNormalizeTest:testIdempotent(int256,int256) (runs: 5109, μ: 9875, ~: 9808) +LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5109, μ: 3533, ~: 3539) +LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5109, μ: 9415, ~: 9348) LibDecimalFloatImplementationPow10Test:testExactLookups() (gas: 1281984) LibDecimalFloatImplementationPow10Test:testExactPows() (gas: 1260129) -LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1369862) -LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 5102, μ: 1270532, ~: 1268592) -LibDecimalFloatImplementationSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5108, μ: 28253, ~: 28480) -LibDecimalFloatImplementationSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5108, μ: 21162, ~: 22944) +LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1282922) +LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 5103, μ: 1258761, ~: 1259054) +LibDecimalFloatImplementationSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5109, μ: 15687, ~: 15706) +LibDecimalFloatImplementationSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5109, μ: 14808, ~: 14740) LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentExamples() (gas: 13429) LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5101, μ: 14426, ~: 14395) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5108, μ: 13307, ~: 13527) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5108, μ: 11668, ~: 11718) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5108, μ: 3676, ~: 3676) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5103, μ: 13874, ~: 13665) -LibDecimalFloatInvTest:testInvMem(bytes32) (runs: 5108, μ: 7321, ~: 7246) -LibDecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5108, μ: 3899, ~: 3899) -LibDecimalFloatIsZeroTest:testIsZeroEqZero(bytes32) (runs: 5108, μ: 3527, ~: 3527) -LibDecimalFloatIsZeroTest:testIsZeroExamples(int32) (runs: 5108, μ: 4477, ~: 4477) -LibDecimalFloatIsZeroTest:testNotIsZero(int224,int32) (runs: 5106, μ: 3896, ~: 3896) -LibDecimalFloatLog10Test:testLog10Packed(bytes32) (runs: 5108, μ: 1676566, ~: 1319587) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5109, μ: 13307, ~: 13527) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5109, μ: 11668, ~: 11718) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5109, μ: 3676, ~: 3676) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5104, μ: 13874, ~: 13665) +LibDecimalFloatInvTest:testInvMem(bytes32) (runs: 5109, μ: 7321, ~: 7246) +LibDecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5109, μ: 3899, ~: 3899) +LibDecimalFloatIsZeroTest:testIsZeroEqZero(bytes32) (runs: 5109, μ: 3527, ~: 3527) +LibDecimalFloatIsZeroTest:testIsZeroExamples(int32) (runs: 5109, μ: 4477, ~: 4477) +LibDecimalFloatIsZeroTest:testNotIsZero(int224,int32) (runs: 5107, μ: 3896, ~: 3896) +LibDecimalFloatLog10Test:testLog10Packed(bytes32) (runs: 5109, μ: 1650376, ~: 1269941) LibDecimalFloatLtTest:testLtExamples() (gas: 3994) LibDecimalFloatLtTest:testLtGasAZero() (gas: 946) LibDecimalFloatLtTest:testLtGasBZero() (gas: 1012) LibDecimalFloatLtTest:testLtGasBothZero() (gas: 969) LibDecimalFloatLtTest:testLtGasDifferentSigns() (gas: 969) LibDecimalFloatLtTest:testLtGasExponentDiffOverflow() (gas: 1053) -LibDecimalFloatLtTest:testLtNegativeVsPositive(int256,int32,int256,int32) (runs: 5108, μ: 13750, ~: 13593) -LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int32,int32) (runs: 5108, μ: 10790, ~: 11008) -LibDecimalFloatLtTest:testLtOneEAny(int224,int32) (runs: 5108, μ: 3905, ~: 3905) -LibDecimalFloatLtTest:testLtReference(bytes32,bytes32) (runs: 5108, μ: 4697, ~: 4998) -LibDecimalFloatLtTest:testLtVsEqualVsGt(bytes32,bytes32) (runs: 5108, μ: 4323, ~: 4210) -LibDecimalFloatLtTest:testLtX(int224) (runs: 5108, μ: 3798, ~: 3798) -LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int32,int32) (runs: 5108, μ: 10557, ~: 10297) -LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5108, μ: 11153, ~: 11359) -LibDecimalFloatLtTest:testLtZero(int32,int32) (runs: 5108, μ: 4171, ~: 4171) +LibDecimalFloatLtTest:testLtNegativeVsPositive(int256,int32,int256,int32) (runs: 5109, μ: 13749, ~: 13593) +LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int32,int32) (runs: 5109, μ: 10790, ~: 11008) +LibDecimalFloatLtTest:testLtOneEAny(int224,int32) (runs: 5109, μ: 3905, ~: 3905) +LibDecimalFloatLtTest:testLtReference(bytes32,bytes32) (runs: 5109, μ: 4697, ~: 4998) +LibDecimalFloatLtTest:testLtVsEqualVsGt(bytes32,bytes32) (runs: 5109, μ: 4323, ~: 4210) +LibDecimalFloatLtTest:testLtX(int224) (runs: 5109, μ: 3798, ~: 3798) +LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int32,int32) (runs: 5109, μ: 10558, ~: 10297) +LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5109, μ: 11153, ~: 11359) +LibDecimalFloatLtTest:testLtZero(int32,int32) (runs: 5109, μ: 4171, ~: 4171) LibDecimalFloatLteTest:testLteGasAZero() (gas: 997) LibDecimalFloatLteTest:testLteGasBZero() (gas: 999) LibDecimalFloatLteTest:testLteGasBothZero() (gas: 753) LibDecimalFloatLteTest:testLteGasDifferentSigns() (gas: 976) LibDecimalFloatLteTest:testLteGasExponentDiffOverflow() (gas: 1082) -LibDecimalFloatLteTest:testLteOneEAny(bytes32) (runs: 5108, μ: 3493, ~: 3493) -LibDecimalFloatLteTest:testLteReference(int224,int32,int224,int32) (runs: 5108, μ: 8109, ~: 6315) -LibDecimalFloatLteTest:testLteX(int224,int32) (runs: 5108, μ: 3904, ~: 3904) -LibDecimalFloatLteTest:testLteXEAnyVsXEAny(int256,int32,int32) (runs: 5108, μ: 10582, ~: 10321) -LibDecimalFloatLteTest:testLteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5108, μ: 11177, ~: 11383) -LibDecimalFloatLteTest:testLteXNotLtY(bytes32,bytes32) (runs: 5108, μ: 3882, ~: 3807) -LibDecimalFloatLteTest:testLteXPositiveYNegative(int256,int32,int256,int32) (runs: 5108, μ: 13103, ~: 12931) -LibDecimalFloatLteTest:testLteXPositiveYZero(int256,int32,int32) (runs: 5108, μ: 9575, ~: 9191) -LibDecimalFloatLteTest:testLteZero(int32,int32) (runs: 5108, μ: 4816, ~: 4816) -LibDecimalFloatMaxTest:testMaxX(bytes32) (runs: 5108, μ: 4246, ~: 4246) -LibDecimalFloatMaxTest:testMaxXY(bytes32,bytes32) (runs: 5108, μ: 4689, ~: 4613) -LibDecimalFloatMaxTest:testMaxXYEqual(bytes32) (runs: 5108, μ: 5272, ~: 5272) -LibDecimalFloatMaxTest:testMaxXYGreater(bytes32,bytes32) (runs: 5103, μ: 6129, ~: 6016) +LibDecimalFloatLteTest:testLteOneEAny(bytes32) (runs: 5109, μ: 3493, ~: 3493) +LibDecimalFloatLteTest:testLteReference(int224,int32,int224,int32) (runs: 5109, μ: 8109, ~: 6315) +LibDecimalFloatLteTest:testLteX(int224,int32) (runs: 5109, μ: 3904, ~: 3904) +LibDecimalFloatLteTest:testLteXEAnyVsXEAny(int256,int32,int32) (runs: 5109, μ: 10583, ~: 10321) +LibDecimalFloatLteTest:testLteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5109, μ: 11177, ~: 11383) +LibDecimalFloatLteTest:testLteXNotLtY(bytes32,bytes32) (runs: 5109, μ: 3882, ~: 3807) +LibDecimalFloatLteTest:testLteXPositiveYNegative(int256,int32,int256,int32) (runs: 5109, μ: 13103, ~: 12931) +LibDecimalFloatLteTest:testLteXPositiveYZero(int256,int32,int32) (runs: 5109, μ: 9575, ~: 9191) +LibDecimalFloatLteTest:testLteZero(int32,int32) (runs: 5109, μ: 4816, ~: 4816) +LibDecimalFloatMaxTest:testMaxX(bytes32) (runs: 5109, μ: 4246, ~: 4246) +LibDecimalFloatMaxTest:testMaxXY(bytes32,bytes32) (runs: 5109, μ: 4689, ~: 4613) +LibDecimalFloatMaxTest:testMaxXYEqual(bytes32) (runs: 5109, μ: 5272, ~: 5272) +LibDecimalFloatMaxTest:testMaxXYGreater(bytes32,bytes32) (runs: 5104, μ: 6129, ~: 6016) LibDecimalFloatMaxTest:testMaxXYLess(bytes32,bytes32) (runs: 5101, μ: 6141, ~: 6027) -LibDecimalFloatMinTest:testMinX(bytes32) (runs: 5108, μ: 4268, ~: 4268) -LibDecimalFloatMinTest:testMinXY(bytes32,bytes32) (runs: 5108, μ: 4689, ~: 4613) -LibDecimalFloatMinTest:testMinXYEqual(bytes32) (runs: 5108, μ: 5292, ~: 5292) -LibDecimalFloatMinTest:testMinXYGreater(bytes32,bytes32) (runs: 5104, μ: 6074, ~: 5961) +LibDecimalFloatMinTest:testMinX(bytes32) (runs: 5109, μ: 4268, ~: 4268) +LibDecimalFloatMinTest:testMinXY(bytes32,bytes32) (runs: 5109, μ: 4689, ~: 4613) +LibDecimalFloatMinTest:testMinXYEqual(bytes32) (runs: 5109, μ: 5292, ~: 5292) +LibDecimalFloatMinTest:testMinXYGreater(bytes32,bytes32) (runs: 5105, μ: 6074, ~: 5961) LibDecimalFloatMinTest:testMinXYLess(bytes32,bytes32) (runs: 5100, μ: 6087, ~: 5972) -LibDecimalFloatMinusTest:testMinusPacked(bytes32) (runs: 5108, μ: 5550, ~: 5550) +LibDecimalFloatMinusTest:testMinusPacked(bytes32) (runs: 5109, μ: 5550, ~: 5550) LibDecimalFloatMixedTest:testDiv1Over3() (gas: 8161) -LibDecimalFloatMulTest:testMulPacked(bytes32,bytes32) (runs: 5108, μ: 7891, ~: 8837) -LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5108, μ: 5352, ~: 5352) -LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5108, μ: 1646693, ~: 1276690) -LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5108, μ: 1248480, ~: 1248447) -LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 5102, μ: 1246471, ~: 1246471) +LibDecimalFloatMulTest:testMulPacked(bytes32,bytes32) (runs: 5109, μ: 7891, ~: 8837) +LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5109, μ: 5352, ~: 5352) +LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5109, μ: 1644878, ~: 1257626) +LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5109, μ: 1248478, ~: 1248447) +LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 5103, μ: 1246471, ~: 1246471) LibDecimalFloatPowTest:testPowAZeroNegative(bytes32) (runs: 5098, μ: 1246870, ~: 1246870) -LibDecimalFloatPowTest:testPowBZero(bytes32,int32) (runs: 5108, μ: 1246058, ~: 1246058) -LibDecimalFloatPowTest:testPows() (gas: 1360903) -LibDecimalFloatPowTest:testRoundTripFuzzPow(bytes32,bytes32) (runs: 5108, μ: 1285399, ~: 1281267) -LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1672185) -LibDecimalFloatSqrtTest:testRoundTripFuzzSqrt(int224,int32) (runs: 5108, μ: 1346450, ~: 1335395) -LibDecimalFloatSqrtTest:testSqrt() (gas: 1331739) -LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5108, μ: 1248101, ~: 1248059) -LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1547274) -LibDecimalFloatSubTest:testSubPacked(bytes32,bytes32) (runs: 5108, μ: 17219, ~: 10557) +LibDecimalFloatPowTest:testPowBZero(bytes32,int32) (runs: 5109, μ: 1246058, ~: 1246058) +LibDecimalFloatPowTest:testPows() (gas: 1305439) +LibDecimalFloatPowTest:testRoundTripFuzzPow(bytes32,bytes32) (runs: 5109, μ: 1260110, ~: 1256782) +LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1455217) +LibDecimalFloatSqrtTest:testRoundTripFuzzSqrt(int224,int32) (runs: 5109, μ: 1288362, ~: 1285857) +LibDecimalFloatSqrtTest:testSqrt() (gas: 1289575) +LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5109, μ: 1248100, ~: 1248059) +LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1384444) +LibDecimalFloatSubTest:testSubPacked(bytes32,bytes32) (runs: 5109, μ: 9673, ~: 9793) LibFormatDecimalFloatTest:testFormatDecimalExamples() (gas: 133439) -LibFormatDecimalFloatTest:testFormatDecimalRoundTrip(uint256) (runs: 5108, μ: 25219, ~: 20105) -LibFormatDecimalFloatTest:testFormatDecimalRoundTripNegative(int256) (runs: 5108, μ: 19679, ~: 21006) +LibFormatDecimalFloatTest:testFormatDecimalRoundTrip(uint256) (runs: 5109, μ: 25218, ~: 20105) +LibFormatDecimalFloatTest:testFormatDecimalRoundTripNegative(int256) (runs: 5109, μ: 19679, ~: 21006) LibLogTableBytesTest:testToBytesAntiLogTableDec() (gas: 159794) LibLogTableBytesTest:testToBytesAntiLogTableDecSmall() (gas: 162322) LibLogTableBytesTest:testToBytesLogTableDec() (gas: 143165) @@ -285,7 +288,7 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatEDot() (gas: 4190) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert5() (gas: 4176) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert6() (gas: 4188) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponents() (gas: 402635) -LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5108, μ: 45908, ~: 37394) +LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5109, μ: 45902, ~: 37394) LibParseDecimalFloatTest:testParseLiteralDecimalFloatLeadingZeros() (gas: 59779) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeE() (gas: 6100) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeFrac() (gas: 5137) @@ -293,5 +296,5 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert0() (gas: 27 LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert1() (gas: 24801) LibParseDecimalFloatTest:testParseLiteralDecimalFloatSpecific() (gas: 22959) LibParseDecimalFloatTest:testParseLiteralDecimalFloatUnrelated() (gas: 50856) -LibParseDecimalFloatTest:testParsePacked(string) (runs: 5108, μ: 9786, ~: 9668) -TestDecimalFloatUnpackTest:testUnpackDeployed(bytes32) (runs: 5108, μ: 158422, ~: 158422) \ No newline at end of file +LibParseDecimalFloatTest:testParsePacked(string) (runs: 5109, μ: 9786, ~: 9668) +TestDecimalFloatUnpackTest:testUnpackDeployed(bytes32) (runs: 5109, μ: 158422, ~: 158422) \ No newline at end of file diff --git a/test/src/lib/LibDecimalFloat.ceil.t.sol b/test/src/lib/LibDecimalFloat.ceil.t.sol index e4adf22b..b5b8602d 100644 --- a/test/src/lib/LibDecimalFloat.ceil.t.sol +++ b/test/src/lib/LibDecimalFloat.ceil.t.sol @@ -13,14 +13,18 @@ contract LibDecimalFloatCeilTest is Test { x.ceil(); } - function checkCeil(int256 x, int256 exponent, int256 expectedSignedCoefficient, int256 expectedExponent) - internal - pure - { - (x, exponent) = LibDecimalFloat.ceil(LibDecimalFloat.packLossless(x, exponent)).unpack(); + function checkCeil( + int256 signedCoefficient, + int256 exponent, + int256 expectedSignedCoefficient, + int256 expectedExponent + ) internal pure { + (signedCoefficient, exponent) = + LibDecimalFloat.ceil(LibDecimalFloat.packLossless(signedCoefficient, exponent)).unpack(); - if (!LibDecimalFloatImplementation.eq(x, exponent, expectedSignedCoefficient, expectedExponent)) { - console2.log("x", x); + if (!LibDecimalFloatImplementation.eq(signedCoefficient, exponent, expectedSignedCoefficient, expectedExponent)) + { + console2.log("signedCoefficient", signedCoefficient); console2.log("exponent", exponent); console2.log("expectedSignedCoefficient", expectedSignedCoefficient); console2.log("expectedExponent", expectedExponent); From 783dda0aa83557ddf279c266b1f5c9cca6462c83 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 18:30:32 +0400 Subject: [PATCH 07/14] lint --- test/src/lib/LibDecimalFloat.ceil.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/src/lib/LibDecimalFloat.ceil.t.sol b/test/src/lib/LibDecimalFloat.ceil.t.sol index b5b8602d..8ac62434 100644 --- a/test/src/lib/LibDecimalFloat.ceil.t.sol +++ b/test/src/lib/LibDecimalFloat.ceil.t.sol @@ -9,8 +9,8 @@ import {Test, console2} from "forge-std/Test.sol"; contract LibDecimalFloatCeilTest is Test { using LibDecimalFloat for Float; - function testCeilNotReverts(Float x) external pure { - x.ceil(); + function testCeilNotReverts(Float float) external pure { + float.ceil(); } function checkCeil( From cd44b067f3e9a9ed43f535aec112c1bbbd3e11a1 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 18:37:17 +0400 Subject: [PATCH 08/14] lint --- .../lib/implementation/LibDecimalFloatImplementation.add.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.add.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.add.t.sol index 1351a283..7ee7f0a3 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.add.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.add.t.sol @@ -138,7 +138,7 @@ contract LibDecimalFloatImplementationAddTest is Test { } function testAddingSmallToLargeReturnsLargeExamples() external pure { - // // Establish a baseline. + // Establish a baseline. checkAdd(1e37, 0, 1e37, -37, 10000000000000000000000000000000000001e38, -38); // Show baseline with reversed order. checkAdd(1e37, -37, 1e37, 0, 10000000000000000000000000000000000001e38, -38); From e7c218c931283fba60627f5f00aa48d9a64a6776 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 18:38:52 +0400 Subject: [PATCH 09/14] lint --- test/src/lib/LibDecimalFloat.ceil.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/test/src/lib/LibDecimalFloat.ceil.t.sol b/test/src/lib/LibDecimalFloat.ceil.t.sol index 8ac62434..64a93274 100644 --- a/test/src/lib/LibDecimalFloat.ceil.t.sol +++ b/test/src/lib/LibDecimalFloat.ceil.t.sol @@ -94,7 +94,6 @@ contract LibDecimalFloatCeilTest is Test { checkCeil(type(int224).max, 0, type(int224).max, 0); checkCeil(type(int224).min, 0, type(int224).min, 0); checkCeil(2.5e37, -37, 3e66, -66); - checkCeil(type(int224).max, 0, type(int224).max, 0); } /// Test some zeros. From 69e81db2bb7fc53a63ada60211195938407f3b7d Mon Sep 17 00:00:00 2001 From: David Meister Date: Mon, 11 Aug 2025 18:40:50 +0400 Subject: [PATCH 10/14] Update src/lib/LibDecimalFloat.sol Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- src/lib/LibDecimalFloat.sol | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/lib/LibDecimalFloat.sol b/src/lib/LibDecimalFloat.sol index e5681ff9..293ec470 100644 --- a/src/lib/LibDecimalFloat.sol +++ b/src/lib/LibDecimalFloat.sol @@ -644,12 +644,10 @@ library LibDecimalFloat { (Float result, bool lossless) = packLossy(characteristic, exponent); (lossless); - // If the mantissa is less then zero then the ceil is the characteristic. - // This is because the mantissa is making the original value smaller, so - // dropping it makes the value larger. - // We only add one if the mantissa is greater than zero. In this case, - // when we drop the mantissa the value becomes smaller so we have to add - // one to the characteristic to get the ceil. + // Truncate the fractional part when exponent < 0: + // mantissa < 0 (input < 0) → truncation towards zero increases the value (correct ceil). + // mantissa == 0 → value is already an integer. + // mantissa > 0 (input > 0) → truncation decreases the value, so add 1 to round up. if (mantissa > 0) { result = add(result, FLOAT_ONE); } From ca9851722d997704a97d6882b7e6a33ef57d9ea5 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 18:50:16 +0400 Subject: [PATCH 11/14] lint --- .../LibDecimalFloatImplementation.sol | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/lib/implementation/LibDecimalFloatImplementation.sol b/src/lib/implementation/LibDecimalFloatImplementation.sol index 1e69af3c..816f73b2 100644 --- a/src/lib/implementation/LibDecimalFloatImplementation.sol +++ b/src/lib/implementation/LibDecimalFloatImplementation.sol @@ -198,23 +198,18 @@ library LibDecimalFloatImplementation { } } - /// Add two floats together as a normalized result. + /// Add two floats together. /// /// Note that because the input values can have arbitrary exponents that may - /// be very far apart, the normalization process is necessarily lossy. - /// For example, normalized 1 is 1e37 coefficient and -37 exponent. - /// Consider adding 1e37 coefficient with exponent 1. - /// These two numbers are identical in coefficient but their exponents are - /// 38 OOMs apart. While we can perform the addition and get the correct - /// result internally, as soon as we normalize the result, we will lose - /// precision and the result will be 1e37 coefficient with -37 exponent. - /// The precision of addition is therefore best case the full 37 decimals - /// representable in normalized form, if the two numbers share the same - /// exponent, but each step of exponent difference will lose a decimal of - /// precision in the output. In practise, this rarely matters as the onchain - /// conventions for amounts are typically 18 decimals or less, and so entire - /// token supplies are typically representable within ~26-33 decimals of - /// precision, making addition lossless for all actual possible values. + /// be very far apart, the addition process is necessarily lossy. + /// Consider adding 1e100 to 1e-100, for example. The result is 1e100. + /// This is because we can't fit 200 OOMs of precision into the result. + /// However, we can easily fit ~26-33 decimals of precision into values, + /// which covers most or all token supplies and amounts we care about in + /// practice. This means that addition is typically lossless for all values + /// we will receive onchain. However, precision loss is still to be expected + /// when combined with other operations such as division that can result in + /// infinite recursion such a 1/3. /// /// https://speleotrove.com/decimal/daops.html#refaddsub /// > add and subtract both take two operands. If either operand is a special From f07e43eca31380066635b0e374b86f85c4a28fe7 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 18:52:24 +0400 Subject: [PATCH 12/14] lint --- test/src/lib/LibDecimalFloat.ceil.t.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/test/src/lib/LibDecimalFloat.ceil.t.sol b/test/src/lib/LibDecimalFloat.ceil.t.sol index 64a93274..7295a8c3 100644 --- a/test/src/lib/LibDecimalFloat.ceil.t.sol +++ b/test/src/lib/LibDecimalFloat.ceil.t.sol @@ -55,7 +55,6 @@ contract LibDecimalFloatCeilTest is Test { int256 scale = int256(10 ** uint256(-exponent)); int256 characteristic = x / scale; - console2.logInt(characteristic); if (characteristic == 0) { if (x > 0) { // If the characteristic is 0 and x is positive then the ceil is 1. From ee2857ba45316711b3d7f9d14c0402d904022f3c Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 19:04:15 +0400 Subject: [PATCH 13/14] ceil in decimal float --- .gas-snapshot | 69 ++++++++++++----------- src/concrete/DecimalFloat.sol | 7 +++ test/src/concrete/DecimalFloat.ceil.t.sol | 27 +++++++++ 3 files changed, 69 insertions(+), 34 deletions(-) create mode 100644 test/src/concrete/DecimalFloat.ceil.t.sol diff --git a/.gas-snapshot b/.gas-snapshot index 18725d40..4b70d21a 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,41 +1,42 @@ -DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5109, μ: 2544181, ~: 2544123) -DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5109, μ: 2548014, ~: 2548093) -DecimalFloatConstantsTest:testEDeployed() (gas: 2543388) -DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2543420) -DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2543356) -DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2543331) -DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2543310) -DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5109, μ: 2546680, ~: 2546536) -DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5109, μ: 2544589, ~: 2544513) -DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5109, μ: 2544041, ~: 2543856) -DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5109, μ: 2548169, ~: 2547999) -DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5109, μ: 2544433, ~: 2544416) -DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5109, μ: 2544988, ~: 2544920) -DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5109, μ: 2545476, ~: 2545390) -DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5109, μ: 2544508, ~: 2544433) -DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5109, μ: 2544582, ~: 2544506) -DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5109, μ: 2545771, ~: 2545696) -DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5109, μ: 2543698, ~: 2543698) -DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5109, μ: 2544486, ~: 2544410) -DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5109, μ: 2544538, ~: 2544463) -DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5109, μ: 2544569, ~: 2544507) -DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5109, μ: 2544567, ~: 2544505) -DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5109, μ: 2544258, ~: 2544258) -DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5109, μ: 2546471, ~: 2547530) +DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5109, μ: 2583700, ~: 2583643) +DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5109, μ: 2587458, ~: 2587547) +DecimalFloatCeilTest:testCeilDeployed(bytes32) (runs: 5109, μ: 2583713, ~: 2583356) +DecimalFloatConstantsTest:testEDeployed() (gas: 2582886) +DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2582918) +DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2582876) +DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2582851) +DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2582830) +DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5109, μ: 2586179, ~: 2586034) +DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5109, μ: 2584085, ~: 2584011) +DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5109, μ: 2583540, ~: 2583354) +DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5109, μ: 2587706, ~: 2587519) +DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5109, μ: 2583930, ~: 2583914) +DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5109, μ: 2584484, ~: 2584418) +DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5109, μ: 2584969, ~: 2584888) +DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5109, μ: 2584029, ~: 2583953) +DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5109, μ: 2584014, ~: 2583939) +DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5109, μ: 2585267, ~: 2585194) +DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5109, μ: 2583196, ~: 2583196) +DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5109, μ: 2584006, ~: 2583930) +DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5109, μ: 2584059, ~: 2583983) +DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5109, μ: 2584067, ~: 2584005) +DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5109, μ: 2584086, ~: 2584025) +DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5109, μ: 2583801, ~: 2583801) +DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5109, μ: 2585900, ~: 2586961) DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5109, μ: 158769, ~: 158769) -DecimalFloatParseTest:testParseDeployed(string) (runs: 5109, μ: 2547000, ~: 2546870) -DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5109, μ: 2555311, ~: 2552536) -DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5109, μ: 2554549, ~: 2553250) -DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5109, μ: 2548323, ~: 2548397) -DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5109, μ: 2545614, ~: 2545503) -DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5109, μ: 2545751, ~: 2546032) +DecimalFloatParseTest:testParseDeployed(string) (runs: 5109, μ: 2586433, ~: 2586302) +DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5109, μ: 2594767, ~: 2592034) +DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5109, μ: 2594061, ~: 2592748) +DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5109, μ: 2587812, ~: 2587887) +DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5109, μ: 2585122, ~: 2585001) +DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5109, μ: 2585263, ~: 2585530) LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5108, μ: 5121, ~: 5121) LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5109, μ: 10475, ~: 10702) LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5109, μ: 9641, ~: 9392) -LibDecimalFloatCeilTest:testCeilExamples() (gas: 35882) -LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5109, μ: 11439, ~: 11078) -LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5109, μ: 9965, ~: 9830) -LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5109, μ: 8966, ~: 9216) +LibDecimalFloatCeilTest:testCeilExamples() (gas: 35216) +LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5109, μ: 11071, ~: 10712) +LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5109, μ: 9954, ~: 9819) +LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5109, μ: 8953, ~: 9205) LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5109, μ: 592, ~: 411) LibDecimalFloatCeilTest:testCeilZero(int32) (runs: 5109, μ: 5438, ~: 5438) LibDecimalFloatConstantsTest:testFloatE() (gas: 3357) diff --git a/src/concrete/DecimalFloat.sol b/src/concrete/DecimalFloat.sol index f3dd675b..f9afd585 100644 --- a/src/concrete/DecimalFloat.sol +++ b/src/concrete/DecimalFloat.sol @@ -166,6 +166,13 @@ contract DecimalFloat { return a.floor(); } + /// Exposes `LibDecimalFloat.ceil` for offchain use. + /// @param a The float to get the ceiling of. + /// @return The ceiled float. + function ceil(Float a) external pure returns (Float) { + return a.ceil(); + } + /// Exposes `LibDecimalFloat.pow10` for offchain use. /// @param a The float to raise to the power of 10. /// @return The result of raising the float to the power of 10. diff --git a/test/src/concrete/DecimalFloat.ceil.t.sol b/test/src/concrete/DecimalFloat.ceil.t.sol new file mode 100644 index 00000000..779edd9e --- /dev/null +++ b/test/src/concrete/DecimalFloat.ceil.t.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +import {LibDecimalFloat, Float} from "src/lib/LibDecimalFloat.sol"; +import {Test} from "forge-std/Test.sol"; +import {DecimalFloat} from "src/concrete/DecimalFloat.sol"; + +contract DecimalFloatCeilTest is Test { + using LibDecimalFloat for Float; + + function ceilExternal(Float a) external pure returns (Float) { + return a.ceil(); + } + + function testCeilDeployed(Float a) external { + DecimalFloat deployed = new DecimalFloat(); + + try this.ceilExternal(a) returns (Float b) { + Float deployedB = deployed.ceil(a); + + assertEq(Float.unwrap(b), Float.unwrap(deployedB)); + } catch (bytes memory err) { + vm.expectRevert(err); + deployed.ceil(a); + } + } +} \ No newline at end of file From f9bbbe755c6ca95d7504f42b72ceded7d1f34324 Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Mon, 11 Aug 2025 19:17:03 +0400 Subject: [PATCH 14/14] gas lint --- .gas-snapshot | 70 +++++++++++------------ src/lib/LibDecimalFloat.sol | 12 ++-- test/src/concrete/DecimalFloat.ceil.t.sol | 2 +- 3 files changed, 41 insertions(+), 43 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 4b70d21a..2333b2b4 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,43 +1,43 @@ -DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5109, μ: 2583700, ~: 2583643) -DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5109, μ: 2587458, ~: 2587547) -DecimalFloatCeilTest:testCeilDeployed(bytes32) (runs: 5109, μ: 2583713, ~: 2583356) -DecimalFloatConstantsTest:testEDeployed() (gas: 2582886) -DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2582918) -DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2582876) -DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2582851) -DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2582830) -DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5109, μ: 2586179, ~: 2586034) -DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5109, μ: 2584085, ~: 2584011) -DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5109, μ: 2583540, ~: 2583354) -DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5109, μ: 2587706, ~: 2587519) -DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5109, μ: 2583930, ~: 2583914) -DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5109, μ: 2584484, ~: 2584418) -DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5109, μ: 2584969, ~: 2584888) -DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5109, μ: 2584029, ~: 2583953) -DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5109, μ: 2584014, ~: 2583939) -DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5109, μ: 2585267, ~: 2585194) -DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5109, μ: 2583196, ~: 2583196) -DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5109, μ: 2584006, ~: 2583930) -DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5109, μ: 2584059, ~: 2583983) -DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5109, μ: 2584067, ~: 2584005) -DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5109, μ: 2584086, ~: 2584025) -DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5109, μ: 2583801, ~: 2583801) -DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5109, μ: 2585900, ~: 2586961) +DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5109, μ: 2594522, ~: 2594465) +DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5109, μ: 2598288, ~: 2598369) +DecimalFloatCeilTest:testCeilDeployed(bytes32) (runs: 5109, μ: 2594530, ~: 2594178) +DecimalFloatConstantsTest:testEDeployed() (gas: 2593708) +DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2593740) +DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2593698) +DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2593673) +DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2593652) +DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5109, μ: 2596998, ~: 2596856) +DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5109, μ: 2594908, ~: 2594833) +DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5109, μ: 2594361, ~: 2594176) +DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5109, μ: 2598514, ~: 2598341) +DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5109, μ: 2594752, ~: 2594736) +DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5109, μ: 2595308, ~: 2595240) +DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5109, μ: 2595793, ~: 2595710) +DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5109, μ: 2594850, ~: 2594775) +DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5109, μ: 2594836, ~: 2594761) +DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5109, μ: 2596086, ~: 2596016) +DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5109, μ: 2594018, ~: 2594018) +DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5109, μ: 2594827, ~: 2594752) +DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5109, μ: 2594880, ~: 2594805) +DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5109, μ: 2594889, ~: 2594827) +DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5109, μ: 2594909, ~: 2594847) +DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5109, μ: 2594623, ~: 2594623) +DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5109, μ: 2596724, ~: 2597783) DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5109, μ: 158769, ~: 158769) -DecimalFloatParseTest:testParseDeployed(string) (runs: 5109, μ: 2586433, ~: 2586302) -DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5109, μ: 2594767, ~: 2592034) -DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5109, μ: 2594061, ~: 2592748) -DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5109, μ: 2587812, ~: 2587887) -DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5109, μ: 2585122, ~: 2585001) -DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5109, μ: 2585263, ~: 2585530) +DecimalFloatParseTest:testParseDeployed(string) (runs: 5109, μ: 2597255, ~: 2597124) +DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5109, μ: 2605572, ~: 2602856) +DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5109, μ: 2604890, ~: 2603570) +DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5109, μ: 2598631, ~: 2598717) +DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5109, μ: 2595944, ~: 2595823) +DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5109, μ: 2596079, ~: 2596352) LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5108, μ: 5121, ~: 5121) LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5109, μ: 10475, ~: 10702) LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5109, μ: 9641, ~: 9392) -LibDecimalFloatCeilTest:testCeilExamples() (gas: 35216) -LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5109, μ: 11071, ~: 10712) -LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5109, μ: 9954, ~: 9819) +LibDecimalFloatCeilTest:testCeilExamples() (gas: 28322) +LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5109, μ: 10988, ~: 10706) +LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5109, μ: 10029, ~: 9813) LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5109, μ: 8953, ~: 9205) -LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5109, μ: 592, ~: 411) +LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5109, μ: 589, ~: 411) LibDecimalFloatCeilTest:testCeilZero(int32) (runs: 5109, μ: 5438, ~: 5438) LibDecimalFloatConstantsTest:testFloatE() (gas: 3357) LibDecimalFloatConstantsTest:testFloatHalf() (gas: 3336) diff --git a/src/lib/LibDecimalFloat.sol b/src/lib/LibDecimalFloat.sol index 293ec470..f822fbf7 100644 --- a/src/lib/LibDecimalFloat.sol +++ b/src/lib/LibDecimalFloat.sol @@ -636,21 +636,19 @@ library LibDecimalFloat { LibDecimalFloatImplementation.characteristicMantissa(signedCoefficient, exponent); // If the mantissa is 0, then the float is already an integer. - // No need to repack or other checks. if (mantissa == 0) { return float; } - - (Float result, bool lossless) = packLossy(characteristic, exponent); - (lossless); - // Truncate the fractional part when exponent < 0: // mantissa < 0 (input < 0) → truncation towards zero increases the value (correct ceil). // mantissa == 0 → value is already an integer. // mantissa > 0 (input > 0) → truncation decreases the value, so add 1 to round up. - if (mantissa > 0) { - result = add(result, FLOAT_ONE); + else if (mantissa > 0) { + (characteristic, exponent) = LibDecimalFloatImplementation.add(characteristic, exponent, 1e75, -75); } + + (Float result, bool lossless) = packLossy(characteristic, exponent); + (lossless); return result; } diff --git a/test/src/concrete/DecimalFloat.ceil.t.sol b/test/src/concrete/DecimalFloat.ceil.t.sol index 779edd9e..36fb01e5 100644 --- a/test/src/concrete/DecimalFloat.ceil.t.sol +++ b/test/src/concrete/DecimalFloat.ceil.t.sol @@ -24,4 +24,4 @@ contract DecimalFloatCeilTest is Test { deployed.ceil(a); } } -} \ No newline at end of file +}