diff --git a/.gas-snapshot b/.gas-snapshot index 67f4143e..086fc50b 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,277 +1,277 @@ -DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5118, μ: 2575478, ~: 2575421) -DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5118, μ: 2579527, ~: 2579617) -DecimalFloatCeilTest:testCeilDeployed(bytes32) (runs: 5118, μ: 2575504, ~: 2575134) -DecimalFloatConstantsTest:testEDeployed() (gas: 2574664) -DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2574696) -DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2574654) -DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2574629) -DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2574608) -DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5118, μ: 2578204, ~: 2578195) -DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5118, μ: 2575864, ~: 2575789) -DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5118, μ: 2575316, ~: 2575132) -DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5118, μ: 2579467, ~: 2579297) -DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5118, μ: 2575708, ~: 2575692) -DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5118, μ: 2576261, ~: 2576196) -DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5118, μ: 2576747, ~: 2576666) -DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5118, μ: 2575806, ~: 2575731) -DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5118, μ: 2575791, ~: 2575717) -DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5118, μ: 2577047, ~: 2576972) -DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5118, μ: 2574974, ~: 2574974) -DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5118, μ: 2575783, ~: 2575708) -DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5118, μ: 2575837, ~: 2575761) -DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5118, μ: 2575845, ~: 2575783) -DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5118, μ: 2575865, ~: 2575803) -DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5118, μ: 2575579, ~: 2575579) -DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5118, μ: 2577678, ~: 2578739) -DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5118, μ: 158769, ~: 158769) -DecimalFloatParseTest:testParseDeployed(string) (runs: 5118, μ: 2578211, ~: 2578080) -DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5118, μ: 2586874, ~: 2583812) -DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5118, μ: 2586169, ~: 2584526) -DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5118, μ: 2579886, ~: 2579917) -DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5118, μ: 2576909, ~: 2576779) -DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5118, μ: 2577046, ~: 2577308) -LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5117, μ: 5121, ~: 5121) -LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5118, μ: 10475, ~: 10702) -LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5118, μ: 9640, ~: 9392) +DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5096, μ: 2657875, ~: 2657817) +DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5096, μ: 2661931, ~: 2662013) +DecimalFloatCeilTest:testCeilDeployed(bytes32) (runs: 5096, μ: 2657902, ~: 2657530) +DecimalFloatConstantsTest:testEDeployed() (gas: 2657060) +DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2657092) +DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2657050) +DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2657025) +DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2657004) +DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5096, μ: 2662969, ~: 2663034) +DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5096, μ: 2658260, ~: 2658185) +DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5096, μ: 2657712, ~: 2657528) +DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5096, μ: 2661880, ~: 2661721) +DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5096, μ: 2658104, ~: 2658088) +DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5096, μ: 2658659, ~: 2658592) +DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5096, μ: 2659145, ~: 2659062) +DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5096, μ: 2658201, ~: 2658127) +DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5096, μ: 2658187, ~: 2658113) +DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5096, μ: 2661791, ~: 2661828) +DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5096, μ: 2657370, ~: 2657370) +DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5096, μ: 2658178, ~: 2658104) +DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5096, μ: 2658231, ~: 2658157) +DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5096, μ: 2658240, ~: 2658179) +DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5096, μ: 2658261, ~: 2658199) +DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5096, μ: 2657975, ~: 2657975) +DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5096, μ: 2660075, ~: 2661135) +DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5096, μ: 158769, ~: 158769) +DecimalFloatParseTest:testParseDeployed(string) (runs: 5096, μ: 2660608, ~: 2660477) +DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5096, μ: 2669675, ~: 2666208) +DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5096, μ: 2669032, ~: 2666922) +DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5096, μ: 2662292, ~: 2662313) +DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5096, μ: 2659274, ~: 2659175) +DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5096, μ: 2659415, ~: 2659704) +LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5096, μ: 5121, ~: 5121) +LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5096, μ: 10475, ~: 10702) +LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5096, μ: 9641, ~: 9392) LibDecimalFloatCeilTest:testCeilExamples() (gas: 30794) -LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5118, μ: 11042, ~: 10713) -LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5118, μ: 10060, ~: 9820) -LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5118, μ: 8961, ~: 9212) -LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5118, μ: 598, ~: 411) -LibDecimalFloatCeilTest:testCeilZero(int32) (runs: 5118, μ: 5438, ~: 5438) +LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5096, μ: 11040, ~: 10713) +LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5096, μ: 10059, ~: 9820) +LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5096, μ: 8961, ~: 9212) +LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5096, μ: 598, ~: 411) +LibDecimalFloatCeilTest:testCeilZero(int32) (runs: 5096, μ: 5438, ~: 5438) LibDecimalFloatConstantsTest:testFloatE() (gas: 3357) LibDecimalFloatConstantsTest:testFloatHalf() (gas: 3336) LibDecimalFloatConstantsTest:testFloatMaxNegativeValue() (gas: 3379) -LibDecimalFloatConstantsTest:testFloatMaxNegativeValueIsMax(bytes32) (runs: 5118, μ: 4488, ~: 4594) +LibDecimalFloatConstantsTest:testFloatMaxNegativeValueIsMax(bytes32) (runs: 5096, μ: 4488, ~: 4594) LibDecimalFloatConstantsTest:testFloatMaxPositiveValue() (gas: 3335) -LibDecimalFloatConstantsTest:testFloatMaxPositiveValueIsMax(bytes32) (runs: 5118, μ: 3545, ~: 3586) +LibDecimalFloatConstantsTest:testFloatMaxPositiveValueIsMax(bytes32) (runs: 5096, μ: 3545, ~: 3586) LibDecimalFloatConstantsTest:testFloatMinNegativeValue() (gas: 3335) -LibDecimalFloatConstantsTest:testFloatMinNegativeValueIsMin(bytes32) (runs: 5118, μ: 3496, ~: 3457) +LibDecimalFloatConstantsTest:testFloatMinNegativeValueIsMin(bytes32) (runs: 5096, μ: 3496, ~: 3457) LibDecimalFloatConstantsTest:testFloatMinPositiveValue() (gas: 3357) -LibDecimalFloatConstantsTest:testFloatMinPositiveValueIsMin(bytes32) (runs: 5118, μ: 4938, ~: 4870) +LibDecimalFloatConstantsTest:testFloatMinPositiveValueIsMin(bytes32) (runs: 5096, μ: 4938, ~: 4870) LibDecimalFloatConstantsTest:testFloatOne() (gas: 3358) LibDecimalFloatConstantsTest:testFloatTwo() (gas: 3380) LibDecimalFloatConstantsTest:testFloatZero() (gas: 3337) -LibDecimalFloatDecimalAddTest:testAddPacked(bytes32,bytes32) (runs: 5118, μ: 9761, ~: 9832) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5113, μ: 9615, ~: 9663) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5118, μ: 8130, ~: 8048) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5118, μ: 7452, ~: 7424) +LibDecimalFloatDecimalAddTest:testAddPacked(bytes32,bytes32) (runs: 5096, μ: 9762, ~: 9832) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5096, μ: 9615, ~: 9663) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5096, μ: 8130, ~: 8048) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5096, μ: 7452, ~: 7424) LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessFail() (gas: 4894) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPacked(bytes32,uint8) (runs: 5118, μ: 6719, ~: 6161) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5118, μ: 15805, ~: 15768) -LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5118, μ: 9274, ~: 9053) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPacked(bytes32,uint8) (runs: 5096, μ: 6718, ~: 6161) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5096, μ: 15805, ~: 15768) +LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5096, μ: 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: 5118, μ: 9460, ~: 9374) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5118, μ: 5978, ~: 5937) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5118, μ: 7307, ~: 5860) -LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5108, μ: 16005, ~: 15996) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5118, μ: 14963, ~: 14729) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5118, μ: 10151, ~: 9811) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5118, μ: 10825, ~: 11076) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyPacked(bytes32,uint8) (runs: 5118, μ: 6805, ~: 6905) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5106, μ: 15348, ~: 15612) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5118, μ: 14493, ~: 14212) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyPacked(uint256,uint8) (runs: 5096, μ: 9460, ~: 9374) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5096, μ: 5978, ~: 5937) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5096, μ: 7305, ~: 5860) +LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5096, μ: 16005, ~: 15996) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5096, μ: 14964, ~: 14729) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5096, μ: 10152, ~: 9811) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5096, μ: 10825, ~: 11076) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyPacked(bytes32,uint8) (runs: 5096, μ: 6804, ~: 6905) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5096, μ: 15348, ~: 15612) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5096, μ: 14493, ~: 14212) LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncateLossless() (gas: 14523) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5118, μ: 13739, ~: 13602) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5118, μ: 4598, ~: 4598) -LibDecimalFloatDivTest:testDivPacked(bytes32,bytes32) (runs: 5118, μ: 8293, ~: 8263) -LibDecimalFloatEqTest:testEqPacked(bytes32,bytes32) (runs: 5118, μ: 5524, ~: 5450) -LibDecimalFloatEqTest:testEqXNotYExponents(bytes32,bytes32) (runs: 5118, μ: 4341, ~: 4234) -LibDecimalFloatEqTest:testEqZero(int32) (runs: 5118, μ: 5133, ~: 5133) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5096, μ: 13738, ~: 13602) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5096, μ: 4598, ~: 4598) +LibDecimalFloatDivTest:testDivPacked(bytes32,bytes32) (runs: 5096, μ: 10691, ~: 10757) +LibDecimalFloatEqTest:testEqPacked(bytes32,bytes32) (runs: 5096, μ: 5524, ~: 5450) +LibDecimalFloatEqTest:testEqXNotYExponents(bytes32,bytes32) (runs: 5096, μ: 4341, ~: 4234) +LibDecimalFloatEqTest:testEqZero(int32) (runs: 5096, μ: 5133, ~: 5133) LibDecimalFloatFloorTest:testFloorExamples() (gas: 38387) LibDecimalFloatFloorTest:testFloorGas0() (gas: 960) LibDecimalFloatFloorTest:testFloorGasTiny() (gas: 881) LibDecimalFloatFloorTest:testFloorGasZero() (gas: 553) -LibDecimalFloatFloorTest:testFloorInRange(int224,int256) (runs: 5118, μ: 11032, ~: 11044) -LibDecimalFloatFloorTest:testFloorLessThanMin(int224,int256) (runs: 5118, μ: 10284, ~: 10293) -LibDecimalFloatFloorTest:testFloorNonNegative(int224,int256) (runs: 5118, μ: 9546, ~: 9806) -LibDecimalFloatFloorTest:testFloorNotReverts(bytes32) (runs: 5118, μ: 461, ~: 365) +LibDecimalFloatFloorTest:testFloorInRange(int224,int256) (runs: 5096, μ: 11032, ~: 11044) +LibDecimalFloatFloorTest:testFloorLessThanMin(int224,int256) (runs: 5096, μ: 10284, ~: 10293) +LibDecimalFloatFloorTest:testFloorNonNegative(int224,int256) (runs: 5096, μ: 9547, ~: 9806) +LibDecimalFloatFloorTest:testFloorNotReverts(bytes32) (runs: 5096, μ: 461, ~: 365) LibDecimalFloatFracTest:testFracExamples() (gas: 39135) LibDecimalFloatFracTest:testFracGas0() (gas: 960) LibDecimalFloatFracTest:testFracGasTiny() (gas: 836) LibDecimalFloatFracTest:testFracGasZero() (gas: 820) -LibDecimalFloatFracTest:testFracInRange(int224,int256) (runs: 5118, μ: 10847, ~: 10859) -LibDecimalFloatFracTest:testFracLessThanMin(int224,int256) (runs: 5118, μ: 10272, ~: 10280) -LibDecimalFloatFracTest:testFracNonNegative(int224,int256) (runs: 5118, μ: 9805, ~: 10066) -LibDecimalFloatFracTest:testFracNotReverts(bytes32) (runs: 5118, μ: 630, ~: 621) +LibDecimalFloatFracTest:testFracInRange(int224,int256) (runs: 5096, μ: 10847, ~: 10859) +LibDecimalFloatFracTest:testFracLessThanMin(int224,int256) (runs: 5096, μ: 10273, ~: 10280) +LibDecimalFloatFracTest:testFracNonNegative(int224,int256) (runs: 5096, μ: 9806, ~: 10066) +LibDecimalFloatFracTest:testFracNotReverts(bytes32) (runs: 5096, μ: 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: 5118, μ: 3494, ~: 3494) -LibDecimalFloatGtTest:testGtReference(int224,int32,int224,int32) (runs: 5118, μ: 8062, ~: 6272) -LibDecimalFloatGtTest:testGtX(int224,int32) (runs: 5118, μ: 3882, ~: 3882) -LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int32,int32) (runs: 5118, μ: 10592, ~: 10332) -LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5118, μ: 11144, ~: 11349) -LibDecimalFloatGtTest:testGtXNotY(bytes32,bytes32) (runs: 5118, μ: 4341, ~: 4232) -LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int32,int256,int32) (runs: 5118, μ: 13764, ~: 13595) -LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int32,int32) (runs: 5118, μ: 10273, ~: 10026) -LibDecimalFloatGtTest:testGtZero(int32,int32) (runs: 5118, μ: 4793, ~: 4793) +LibDecimalFloatGtTest:testGtOneEAny(bytes32) (runs: 5096, μ: 3494, ~: 3494) +LibDecimalFloatGtTest:testGtReference(int224,int32,int224,int32) (runs: 5096, μ: 8067, ~: 6285) +LibDecimalFloatGtTest:testGtX(int224,int32) (runs: 5096, μ: 3882, ~: 3882) +LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int32,int32) (runs: 5096, μ: 10592, ~: 10332) +LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5096, μ: 11144, ~: 11349) +LibDecimalFloatGtTest:testGtXNotY(bytes32,bytes32) (runs: 5096, μ: 4341, ~: 4232) +LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int32,int256,int32) (runs: 5096, μ: 13764, ~: 13595) +LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int32,int32) (runs: 5096, μ: 10273, ~: 10026) +LibDecimalFloatGtTest:testGtZero(int32,int32) (runs: 5096, μ: 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: 5118, μ: 3494, ~: 3494) -LibDecimalFloatGteTest:testGteReference(int224,int32,int224,int32) (runs: 5118, μ: 8112, ~: 6318) -LibDecimalFloatGteTest:testGteX(int224,int32) (runs: 5118, μ: 3925, ~: 3925) -LibDecimalFloatGteTest:testGteXEAnyVsXEAny(int256,int32,int32) (runs: 5118, μ: 10621, ~: 10364) -LibDecimalFloatGteTest:testGteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5118, μ: 11157, ~: 11361) -LibDecimalFloatGteTest:testGteXNotLtY(bytes32,bytes32) (runs: 5118, μ: 3947, ~: 3873) -LibDecimalFloatGteTest:testGteXPositiveYNegative(int256,int32,int256,int32) (runs: 5118, μ: 13794, ~: 13623) -LibDecimalFloatGteTest:testGteXPositiveYZero(int256,int32,int32) (runs: 5118, μ: 9550, ~: 9170) -LibDecimalFloatGteTest:testGteZero(int32,int32) (runs: 5118, μ: 4838, ~: 4838) +LibDecimalFloatGteTest:testGteOneEAny(bytes32) (runs: 5096, μ: 3494, ~: 3494) +LibDecimalFloatGteTest:testGteReference(int224,int32,int224,int32) (runs: 5096, μ: 8117, ~: 6344) +LibDecimalFloatGteTest:testGteX(int224,int32) (runs: 5096, μ: 3925, ~: 3925) +LibDecimalFloatGteTest:testGteXEAnyVsXEAny(int256,int32,int32) (runs: 5096, μ: 10622, ~: 10364) +LibDecimalFloatGteTest:testGteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5096, μ: 11156, ~: 11361) +LibDecimalFloatGteTest:testGteXNotLtY(bytes32,bytes32) (runs: 5096, μ: 3947, ~: 3873) +LibDecimalFloatGteTest:testGteXPositiveYNegative(int256,int32,int256,int32) (runs: 5096, μ: 13794, ~: 13623) +LibDecimalFloatGteTest:testGteXPositiveYZero(int256,int32,int32) (runs: 5096, μ: 9551, ~: 9170) +LibDecimalFloatGteTest:testGteZero(int32,int32) (runs: 5096, μ: 4838, ~: 4838) LibDecimalFloatImplementationAddTest:testAdd123456789987654321() (gas: 4811) LibDecimalFloatImplementationAddTest:testAdd123456789e9987654321() (gas: 4861) -LibDecimalFloatImplementationAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5118, μ: 13100, ~: 13033) +LibDecimalFloatImplementationAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5096, μ: 13101, ~: 13034) LibDecimalFloatImplementationAddTest:testAddOneOneNotMaximized() (gas: 6148) LibDecimalFloatImplementationAddTest:testAddOneOnePreMaximized() (gas: 4300) LibDecimalFloatImplementationAddTest:testAddOneZero() (gas: 3666) -LibDecimalFloatImplementationAddTest:testAddSameExponent(int256,int256) (runs: 5111, μ: 6864, ~: 6935) +LibDecimalFloatImplementationAddTest:testAddSameExponent(int256,int256) (runs: 5096, μ: 6865, ~: 6935) LibDecimalFloatImplementationAddTest:testAddZero() (gas: 3665) -LibDecimalFloatImplementationAddTest:testAddZeroAnyExponent(int128) (runs: 5118, μ: 9293, ~: 9271) +LibDecimalFloatImplementationAddTest:testAddZeroAnyExponent(int128) (runs: 5096, μ: 9293, ~: 9271) LibDecimalFloatImplementationAddTest:testAddZeroOne() (gas: 3664) -LibDecimalFloatImplementationAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5117, μ: 13974, ~: 13948) +LibDecimalFloatImplementationAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5096, μ: 13974, ~: 13948) LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeExamples() (gas: 92086) -LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5104, μ: 16980, ~: 16963) +LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5096, μ: 16980, ~: 16963) LibDecimalFloatImplementationAddTest:testGasAddOne() (gas: 1342) LibDecimalFloatImplementationAddTest:testGasAddZero() (gas: 360) -LibDecimalFloatImplementationAddTest:testOverflowChecks(int256,int256) (runs: 5118, μ: 3857, ~: 3843) +LibDecimalFloatImplementationAddTest:testOverflowChecks(int256,int256) (runs: 5096, μ: 3857, ~: 3843) LibDecimalFloatImplementationCharacteristicMantissaTest:testCharacteristicMantissaExamples() (gas: 30611) -LibDecimalFloatImplementationDivTest:testDiv1Over3() (gas: 5987) -LibDecimalFloatImplementationDivTest:testDiv1Over3Gas0() (gas: 923) -LibDecimalFloatImplementationDivTest:testDiv1Over3Gas10() (gas: 10560) -LibDecimalFloatImplementationDivTest:testDiv1Over9Over1Over3() (gas: 9596) -LibDecimalFloatImplementationDivTest:testDiv1e18Over3() (gas: 5646) -LibDecimalFloatImplementationDivTest:testDivNegative1Over3() (gas: 6047) -LibDecimalFloatImplementationDivTest:testDivOOMs5and2() (gas: 5055) -LibDecimalFloatImplementationDivTest:testDivOOMsOverTen() (gas: 5957) -LibDecimalFloatImplementationDivTest:testDivTenOverOOMs() (gas: 5551) -LibDecimalFloatImplementationDivTest:testUnnormalizedThreesDiv0(int256,int256) (runs: 122, μ: 20842375, ~: 20842008) +LibDecimalFloatImplementationDivTest:testDiv1Over3() (gas: 6627) +LibDecimalFloatImplementationDivTest:testDiv1Over3Gas0() (gas: 1775) +LibDecimalFloatImplementationDivTest:testDiv1Over3Gas10() (gas: 14642) +LibDecimalFloatImplementationDivTest:testDiv1Over9Over1Over3() (gas: 12815) +LibDecimalFloatImplementationDivTest:testDiv1e18Over3() (gas: 6286) +LibDecimalFloatImplementationDivTest:testDivNegative1Over3() (gas: 6741) +LibDecimalFloatImplementationDivTest:testDivOOMs5and2() (gas: 5907) +LibDecimalFloatImplementationDivTest:testDivOOMsOverTen() (gas: 6597) +LibDecimalFloatImplementationDivTest:testDivTenOverOOMs() (gas: 6510) +LibDecimalFloatImplementationDivTest:testUnnormalizedThreesDiv0(int256,int256) (runs: 100, μ: 24587009, ~: 24586663) 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: 5118, μ: 654, ~: 679) -LibDecimalFloatImplementationEqTest:testEqOneEAny(int256,int256) (runs: 5118, μ: 3416, ~: 3416) -LibDecimalFloatImplementationEqTest:testEqReference(int256,int256,int256,int256) (runs: 5118, μ: 9903, ~: 11446) -LibDecimalFloatImplementationEqTest:testEqX(int256) (runs: 5118, μ: 3392, ~: 3392) -LibDecimalFloatImplementationEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5116, μ: 4718, ~: 4714) -LibDecimalFloatImplementationEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5118, μ: 732, ~: 753) -LibDecimalFloatImplementationEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5118, μ: 3928, ~: 3953) -LibDecimalFloatImplementationEqTest:testEqZero(int256,int256) (runs: 5118, μ: 3440, ~: 3440) -LibDecimalFloatImplementationInvTest:testInvGas0() (gas: 734) -LibDecimalFloatImplementationInvTest:testInvReference(int256,int256) (runs: 5116, μ: 12416, ~: 12356) -LibDecimalFloatImplementationInvTest:testInvSlowGas0() (gas: 948) +LibDecimalFloatImplementationEqTest:testEqNotReverts(int256,int256,int256,int256) (runs: 5096, μ: 654, ~: 679) +LibDecimalFloatImplementationEqTest:testEqOneEAny(int256,int256) (runs: 5096, μ: 3416, ~: 3416) +LibDecimalFloatImplementationEqTest:testEqReference(int256,int256,int256,int256) (runs: 5096, μ: 9904, ~: 11446) +LibDecimalFloatImplementationEqTest:testEqX(int256) (runs: 5096, μ: 3392, ~: 3392) +LibDecimalFloatImplementationEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5096, μ: 4718, ~: 4714) +LibDecimalFloatImplementationEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5096, μ: 732, ~: 753) +LibDecimalFloatImplementationEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5096, μ: 3928, ~: 3953) +LibDecimalFloatImplementationEqTest:testEqZero(int256,int256) (runs: 5096, μ: 3440, ~: 3440) +LibDecimalFloatImplementationInvTest:testInvGas0() (gas: 1602) +LibDecimalFloatImplementationInvTest:testInvReference(int256,int256) (runs: 5096, μ: 13646, ~: 13607) +LibDecimalFloatImplementationInvTest:testInvSlowGas0() (gas: 1786) LibDecimalFloatImplementationLog10Test:testExactLogs() (gas: 1263178) LibDecimalFloatImplementationLog10Test:testExactLookupsLog10() (gas: 1280250) -LibDecimalFloatImplementationLog10Test:testInterpolatedLookups() (gas: 1260273) -LibDecimalFloatImplementationLog10Test:testSub1() (gas: 1256794) -LibDecimalFloatImplementationMaximizeTest:testMaximizedEverything(int256,int256) (runs: 5118, μ: 9478, ~: 9455) +LibDecimalFloatImplementationLog10Test:testInterpolatedLookups() (gas: 1260157) +LibDecimalFloatImplementationLog10Test:testSub1() (gas: 1257848) +LibDecimalFloatImplementationMaximizeTest:testMaximizedEverything(int256,int256) (runs: 5096, μ: 9478, ~: 9455) LibDecimalFloatImplementationMaximizeTest:testMaximizedExamples() (gas: 165819) -LibDecimalFloatImplementationMaximizeTest:testMaximizedIdempotent(int256,int256) (runs: 5118, μ: 9903, ~: 9868) -LibDecimalFloatImplementationMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5118, μ: 12950, ~: 12929) +LibDecimalFloatImplementationMaximizeTest:testMaximizedIdempotent(int256,int256) (runs: 5096, μ: 9904, ~: 9868) +LibDecimalFloatImplementationMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5096, μ: 12949, ~: 12929) LibDecimalFloatImplementationMulTest:testMul123456789987654321() (gas: 3676) -LibDecimalFloatImplementationMulTest:testMul123456789987654321WithExponents(int128,int128) (runs: 5118, μ: 13186, ~: 13270) +LibDecimalFloatImplementationMulTest:testMul123456789987654321WithExponents(int128,int128) (runs: 5096, μ: 13186, ~: 13270) LibDecimalFloatImplementationMulTest:testMul1e181e19() (gas: 3720) LibDecimalFloatImplementationMulTest:testMulGasOne() (gas: 382) LibDecimalFloatImplementationMulTest:testMulGasZero() (gas: 324) -LibDecimalFloatImplementationMulTest:testMulNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5118, μ: 13394, ~: 12563) +LibDecimalFloatImplementationMulTest:testMulNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5096, μ: 13394, ~: 12563) LibDecimalFloatImplementationMulTest:testMulOneOne() (gas: 3721) LibDecimalFloatImplementationMulTest:testMulOneZero() (gas: 3663) LibDecimalFloatImplementationMulTest:testMulZero0Exponent() (gas: 3620) -LibDecimalFloatImplementationMulTest:testMulZeroAnyExponent(int64,int64) (runs: 5118, μ: 3908, ~: 3908) +LibDecimalFloatImplementationMulTest:testMulZeroAnyExponent(int64,int64) (runs: 5096, μ: 3908, ~: 3908) LibDecimalFloatImplementationMulTest:testMulZeroOne() (gas: 3642) LibDecimalFloatImplementationNormalizeTest:testExamples() (gas: 160899) -LibDecimalFloatImplementationNormalizeTest:testIdempotent(int256,int256) (runs: 5118, μ: 9875, ~: 9808) -LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5118, μ: 3533, ~: 3539) -LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5118, μ: 9415, ~: 9348) -LibDecimalFloatImplementationPow10Test:testExactLookups() (gas: 1281984) -LibDecimalFloatImplementationPow10Test:testExactPows() (gas: 1260129) -LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1283750) -LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 5110, μ: 1258970, ~: 1259175) -LibDecimalFloatImplementationSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5118, μ: 15800, ~: 15832) -LibDecimalFloatImplementationSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5118, μ: 14990, ~: 14932) +LibDecimalFloatImplementationNormalizeTest:testIdempotent(int256,int256) (runs: 5096, μ: 9875, ~: 9808) +LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5096, μ: 3533, ~: 3539) +LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5096, μ: 9415, ~: 9348) +LibDecimalFloatImplementationPow10Test:testExactLookupsPow10() (gas: 1282687) +LibDecimalFloatImplementationPow10Test:testExactPows() (gas: 1260107) +LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1283540) +LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 5096, μ: 1259162, ~: 1259873) +LibDecimalFloatImplementationSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5096, μ: 15801, ~: 15834) +LibDecimalFloatImplementationSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5096, μ: 14990, ~: 14932) LibDecimalFloatImplementationSubTest:testSubOneFromMax() (gas: 6517) -LibDecimalFloatImplementationSubTest:testSubSelf(int224,int32) (runs: 5118, μ: 5509, ~: 5620) +LibDecimalFloatImplementationSubTest:testSubSelf(int224,int32) (runs: 5096, μ: 5509, ~: 5620) LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentExamples() (gas: 13429) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5104, μ: 14426, ~: 14395) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5118, μ: 13307, ~: 13527) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5118, μ: 11668, ~: 11718) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5118, μ: 3676, ~: 3676) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5110, μ: 13874, ~: 13665) -LibDecimalFloatInvTest:testInvMem(bytes32) (runs: 5118, μ: 7321, ~: 7246) -LibDecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5118, μ: 3899, ~: 3899) -LibDecimalFloatIsZeroTest:testIsZeroEqZero(bytes32) (runs: 5118, μ: 3527, ~: 3527) -LibDecimalFloatIsZeroTest:testIsZeroExamples(int32) (runs: 5118, μ: 4477, ~: 4477) -LibDecimalFloatIsZeroTest:testNotIsZero(int224,int32) (runs: 5116, μ: 3896, ~: 3896) -LibDecimalFloatLog10Test:testLog10Packed(bytes32) (runs: 5118, μ: 1651243, ~: 1270937) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5096, μ: 14426, ~: 14395) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5096, μ: 13307, ~: 13527) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5096, μ: 11669, ~: 11718) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5096, μ: 3676, ~: 3676) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5096, μ: 13874, ~: 13665) +LibDecimalFloatInvTest:testInvMem(bytes32) (runs: 5096, μ: 9679, ~: 9738) +LibDecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5096, μ: 3899, ~: 3899) +LibDecimalFloatIsZeroTest:testIsZeroEqZero(bytes32) (runs: 5096, μ: 3527, ~: 3527) +LibDecimalFloatIsZeroTest:testIsZeroExamples(int32) (runs: 5096, μ: 4477, ~: 4477) +LibDecimalFloatIsZeroTest:testNotIsZero(int224,int32) (runs: 5096, μ: 3896, ~: 3896) +LibDecimalFloatLog10Test:testLog10Packed(bytes32) (runs: 5096, μ: 1650742, ~: 1270777) 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: 5118, μ: 13749, ~: 13593) -LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int32,int32) (runs: 5118, μ: 10790, ~: 11008) -LibDecimalFloatLtTest:testLtOneEAny(int224,int32) (runs: 5118, μ: 3905, ~: 3905) -LibDecimalFloatLtTest:testLtReference(bytes32,bytes32) (runs: 5118, μ: 4696, ~: 4998) -LibDecimalFloatLtTest:testLtVsEqualVsGt(bytes32,bytes32) (runs: 5118, μ: 4323, ~: 4210) -LibDecimalFloatLtTest:testLtX(int224) (runs: 5118, μ: 3798, ~: 3798) -LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int32,int32) (runs: 5118, μ: 10557, ~: 10297) -LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5118, μ: 11154, ~: 11359) -LibDecimalFloatLtTest:testLtZero(int32,int32) (runs: 5118, μ: 4171, ~: 4171) +LibDecimalFloatLtTest:testLtNegativeVsPositive(int256,int32,int256,int32) (runs: 5096, μ: 13750, ~: 13593) +LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int32,int32) (runs: 5096, μ: 10790, ~: 11008) +LibDecimalFloatLtTest:testLtOneEAny(int224,int32) (runs: 5096, μ: 3905, ~: 3905) +LibDecimalFloatLtTest:testLtReference(bytes32,bytes32) (runs: 5096, μ: 4697, ~: 4998) +LibDecimalFloatLtTest:testLtVsEqualVsGt(bytes32,bytes32) (runs: 5096, μ: 4323, ~: 4210) +LibDecimalFloatLtTest:testLtX(int224) (runs: 5096, μ: 3798, ~: 3798) +LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int32,int32) (runs: 5096, μ: 10557, ~: 10297) +LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5096, μ: 11153, ~: 11359) +LibDecimalFloatLtTest:testLtZero(int32,int32) (runs: 5096, μ: 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: 5118, μ: 3493, ~: 3493) -LibDecimalFloatLteTest:testLteReference(int224,int32,int224,int32) (runs: 5118, μ: 8107, ~: 6315) -LibDecimalFloatLteTest:testLteX(int224,int32) (runs: 5118, μ: 3904, ~: 3904) -LibDecimalFloatLteTest:testLteXEAnyVsXEAny(int256,int32,int32) (runs: 5118, μ: 10582, ~: 10321) -LibDecimalFloatLteTest:testLteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5118, μ: 11177, ~: 11383) -LibDecimalFloatLteTest:testLteXNotLtY(bytes32,bytes32) (runs: 5118, μ: 3882, ~: 3807) -LibDecimalFloatLteTest:testLteXPositiveYNegative(int256,int32,int256,int32) (runs: 5118, μ: 13102, ~: 12931) -LibDecimalFloatLteTest:testLteXPositiveYZero(int256,int32,int32) (runs: 5118, μ: 9574, ~: 9191) -LibDecimalFloatLteTest:testLteZero(int32,int32) (runs: 5118, μ: 4816, ~: 4816) -LibDecimalFloatMaxTest:testMaxX(bytes32) (runs: 5118, μ: 4246, ~: 4246) -LibDecimalFloatMaxTest:testMaxXY(bytes32,bytes32) (runs: 5118, μ: 4689, ~: 4613) -LibDecimalFloatMaxTest:testMaxXYEqual(bytes32) (runs: 5118, μ: 5272, ~: 5272) -LibDecimalFloatMaxTest:testMaxXYGreater(bytes32,bytes32) (runs: 5109, μ: 6129, ~: 6016) -LibDecimalFloatMaxTest:testMaxXYLess(bytes32,bytes32) (runs: 5105, μ: 6141, ~: 6027) -LibDecimalFloatMinTest:testMinX(bytes32) (runs: 5118, μ: 4268, ~: 4268) -LibDecimalFloatMinTest:testMinXY(bytes32,bytes32) (runs: 5118, μ: 4689, ~: 4613) -LibDecimalFloatMinTest:testMinXYEqual(bytes32) (runs: 5118, μ: 5292, ~: 5292) -LibDecimalFloatMinTest:testMinXYGreater(bytes32,bytes32) (runs: 5110, μ: 6074, ~: 5961) -LibDecimalFloatMinTest:testMinXYLess(bytes32,bytes32) (runs: 5104, μ: 6087, ~: 5972) -LibDecimalFloatMinusTest:testMinusPacked(bytes32) (runs: 5118, μ: 5550, ~: 5550) -LibDecimalFloatMixedTest:testDiv1Over3() (gas: 8175) -LibDecimalFloatMulTest:testMulPacked(bytes32,bytes32) (runs: 5118, μ: 7889, ~: 8837) -LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5118, μ: 5352, ~: 5352) -LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5118, μ: 1644250, ~: 1257848) -LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5117, μ: 1248480, ~: 1248447) -LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 5111, μ: 1246471, ~: 1246471) -LibDecimalFloatPowTest:testPowAZeroNegative(bytes32) (runs: 5098, μ: 1246870, ~: 1246870) -LibDecimalFloatPowTest:testPowBZero(bytes32,int32) (runs: 5118, μ: 1246058, ~: 1246058) -LibDecimalFloatPowTest:testPows() (gas: 1307988) -LibDecimalFloatPowTest:testRoundTripFuzzPow(bytes32,bytes32) (runs: 5118, μ: 1260704, ~: 1257620) -LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1466189) -LibDecimalFloatSqrtTest:testRoundTripFuzzSqrt(int224,int32) (runs: 5118, μ: 1291727, ~: 1289446) -LibDecimalFloatSqrtTest:testSqrt() (gas: 1293117) -LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5118, μ: 1248101, ~: 1248059) -LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1392528) -LibDecimalFloatSubTest:testSubPacked(bytes32,bytes32) (runs: 5118, μ: 9973, ~: 9995) +LibDecimalFloatLteTest:testLteOneEAny(bytes32) (runs: 5096, μ: 3493, ~: 3493) +LibDecimalFloatLteTest:testLteReference(int224,int32,int224,int32) (runs: 5096, μ: 8112, ~: 6341) +LibDecimalFloatLteTest:testLteX(int224,int32) (runs: 5096, μ: 3904, ~: 3904) +LibDecimalFloatLteTest:testLteXEAnyVsXEAny(int256,int32,int32) (runs: 5096, μ: 10582, ~: 10321) +LibDecimalFloatLteTest:testLteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5096, μ: 11177, ~: 11383) +LibDecimalFloatLteTest:testLteXNotLtY(bytes32,bytes32) (runs: 5096, μ: 3882, ~: 3807) +LibDecimalFloatLteTest:testLteXPositiveYNegative(int256,int32,int256,int32) (runs: 5096, μ: 13103, ~: 12931) +LibDecimalFloatLteTest:testLteXPositiveYZero(int256,int32,int32) (runs: 5096, μ: 9575, ~: 9191) +LibDecimalFloatLteTest:testLteZero(int32,int32) (runs: 5096, μ: 4816, ~: 4816) +LibDecimalFloatMaxTest:testMaxX(bytes32) (runs: 5096, μ: 4246, ~: 4246) +LibDecimalFloatMaxTest:testMaxXY(bytes32,bytes32) (runs: 5096, μ: 4689, ~: 4613) +LibDecimalFloatMaxTest:testMaxXYEqual(bytes32) (runs: 5096, μ: 5272, ~: 5272) +LibDecimalFloatMaxTest:testMaxXYGreater(bytes32,bytes32) (runs: 5096, μ: 6129, ~: 6016) +LibDecimalFloatMaxTest:testMaxXYLess(bytes32,bytes32) (runs: 5096, μ: 6141, ~: 6027) +LibDecimalFloatMinTest:testMinX(bytes32) (runs: 5096, μ: 4268, ~: 4268) +LibDecimalFloatMinTest:testMinXY(bytes32,bytes32) (runs: 5096, μ: 4689, ~: 4613) +LibDecimalFloatMinTest:testMinXYEqual(bytes32) (runs: 5096, μ: 5292, ~: 5292) +LibDecimalFloatMinTest:testMinXYGreater(bytes32,bytes32) (runs: 5096, μ: 6074, ~: 5961) +LibDecimalFloatMinTest:testMinXYLess(bytes32,bytes32) (runs: 5096, μ: 6087, ~: 5972) +LibDecimalFloatMinusTest:testMinusPacked(bytes32) (runs: 5096, μ: 5550, ~: 5550) +LibDecimalFloatMixedTest:testDiv1Over3Mixed() (gas: 9518) +LibDecimalFloatMulTest:testMulPacked(bytes32,bytes32) (runs: 5096, μ: 7890, ~: 8837) +LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5096, μ: 5352, ~: 5352) +LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5096, μ: 1644472, ~: 1258201) +LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5096, μ: 1248480, ~: 1248447) +LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 5096, μ: 1246471, ~: 1246471) +LibDecimalFloatPowTest:testPowAZeroNegative(bytes32) (runs: 5096, μ: 1246870, ~: 1246870) +LibDecimalFloatPowTest:testPowBZero(bytes32,int32) (runs: 5096, μ: 1246058, ~: 1246058) +LibDecimalFloatPowTest:testPows() (gas: 1312147) +LibDecimalFloatPowTest:testRoundTripFuzzPow(bytes32,bytes32) (runs: 5096, μ: 1261462, ~: 1258766) +LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1508171) +LibDecimalFloatSqrtTest:testRoundTripFuzzSqrt(int224,int32) (runs: 5096, μ: 1293364, ~: 1293233) +LibDecimalFloatSqrtTest:testSqrt() (gas: 1292895) +LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5096, μ: 1248099, ~: 1248059) +LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1400101) +LibDecimalFloatSubTest:testSubPacked(bytes32,bytes32) (runs: 5096, μ: 9974, ~: 9995) LibFormatDecimalFloatTest:testFormatDecimalExamples() (gas: 133439) -LibFormatDecimalFloatTest:testFormatDecimalRoundTrip(uint256) (runs: 5118, μ: 25209, ~: 20105) -LibFormatDecimalFloatTest:testFormatDecimalRoundTripNegative(int256) (runs: 5118, μ: 19675, ~: 21006) +LibFormatDecimalFloatTest:testFormatDecimalRoundTrip(uint256) (runs: 5096, μ: 25219, ~: 20105) +LibFormatDecimalFloatTest:testFormatDecimalRoundTripNegative(int256) (runs: 5096, μ: 19679, ~: 21006) LibLogTableBytesTest:testToBytesAntiLogTableDec() (gas: 159794) LibLogTableBytesTest:testToBytesAntiLogTableDecSmall() (gas: 162322) LibLogTableBytesTest:testToBytesLogTableDec() (gas: 143165) @@ -293,7 +293,7 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatEDot() (gas: 4190) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert5() (gas: 4176) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert6() (gas: 4188) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponents() (gas: 402635) -LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5118, μ: 45938, ~: 37394) +LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5096, μ: 45910, ~: 37386) LibParseDecimalFloatTest:testParseLiteralDecimalFloatLeadingZeros() (gas: 59779) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeE() (gas: 6100) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeFrac() (gas: 5137) @@ -301,5 +301,5 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert0() (gas: 27 LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert1() (gas: 24801) LibParseDecimalFloatTest:testParseLiteralDecimalFloatSpecific() (gas: 22959) LibParseDecimalFloatTest:testParseLiteralDecimalFloatUnrelated() (gas: 50856) -LibParseDecimalFloatTest:testParsePacked(string) (runs: 5118, μ: 9787, ~: 9668) -TestDecimalFloatUnpackTest:testUnpackDeployed(bytes32) (runs: 5118, μ: 158422, ~: 158422) \ No newline at end of file +LibParseDecimalFloatTest:testParsePacked(string) (runs: 5096, μ: 9787, ~: 9668) +TestDecimalFloatUnpackTest:testUnpackDeployed(bytes32) (runs: 5096, μ: 158422, ~: 158422) \ No newline at end of file diff --git a/crates/float/src/lib.rs b/crates/float/src/lib.rs index 6a835c05..b88b69f6 100644 --- a/crates/float/src/lib.rs +++ b/crates/float/src/lib.rs @@ -1368,7 +1368,10 @@ mod tests { let zero = Float::parse("0".to_string()).unwrap(); let err = (one / zero).unwrap_err(); - assert!(matches!(err, FloatError::Revert(_))); + assert!(matches!( + err, + FloatError::DecimalFloat(DecimalFloatErrors::MulDivOverflow(_)) + )); } #[test] diff --git a/src/error/ErrDecimalFloat.sol b/src/error/ErrDecimalFloat.sol index eef6de0a..cd4cfd0c 100644 --- a/src/error/ErrDecimalFloat.sol +++ b/src/error/ErrDecimalFloat.sol @@ -30,3 +30,6 @@ error LossyConversionFromFloat(int256 signedCoefficient, int256 exponent); /// @dev Thrown when attempting to exponentiate 0^b where b is negative. error ZeroNegativePower(Float b); + +/// @dev Thrown when mulDiv internal to division overflows. +error MulDivOverflow(uint256 x, uint256 y, uint256 denominator); diff --git a/src/lib/implementation/LibDecimalFloatImplementation.sol b/src/lib/implementation/LibDecimalFloatImplementation.sol index 2b1ed275..b0cd5c74 100644 --- a/src/lib/implementation/LibDecimalFloatImplementation.sol +++ b/src/lib/implementation/LibDecimalFloatImplementation.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: CAL pragma solidity ^0.8.25; -import {ExponentOverflow, Log10Negative, Log10Zero} from "../../error/ErrDecimalFloat.sol"; +import {ExponentOverflow, Log10Negative, Log10Zero, MulDivOverflow} from "../../error/ErrDecimalFloat.sol"; import { LOG_TABLES, LOG_TABLES_SMALL, @@ -188,13 +188,149 @@ library LibDecimalFloatImplementation { pure returns (int256, int256) { + uint256 scale = 1e76; + int256 adjustExponent = 76; + int256 signedCoefficient; + unchecked { + // Move both coefficients into the e75/e76 range, so that the result + // of division will not cause a mulDiv overflow. (signedCoefficientA, exponentA) = maximize(signedCoefficientA, exponentA); - (signedCoefficientB, exponentB) = normalize(signedCoefficientB, exponentB); + (signedCoefficientB, exponentB) = maximize(signedCoefficientB, exponentB); + + // mulDiv only works with unsigned integers, so get the absolute + // values of the coefficients. + uint256 signedCoefficientAAbs; + if (signedCoefficientA > 0) { + signedCoefficientAAbs = uint256(signedCoefficientA); + } else if (signedCoefficientA < 0) { + if (signedCoefficientA == type(int256).min) { + signedCoefficientAAbs = uint256(type(int256).max) + 1; + } else { + signedCoefficientAAbs = uint256(-signedCoefficientA); + } + } else { + return (MAXIMIZED_ZERO_SIGNED_COEFFICIENT, MAXIMIZED_ZERO_EXPONENT); + } + uint256 signedCoefficientBAbs; + if (signedCoefficientB < 0) { + if (signedCoefficientB == type(int256).min) { + signedCoefficientBAbs = uint256(type(int256).max) + 1; + } else { + signedCoefficientBAbs = uint256(-signedCoefficientB); + } + } else { + signedCoefficientBAbs = uint256(signedCoefficientB); + } - int256 signedCoefficient = signedCoefficientA / signedCoefficientB; - int256 exponent = exponentA - exponentB; - return (signedCoefficient, exponent); + // We are going to scale the numerator up by the largest power of ten + // that is smaller than the denominator. This will always overflow + // internally to the mulDiv during the initial multiplication, in + // 512 bits, but will subsequently always be reduced back down to + // fit in 256 bits by the division of a denominator that is larger + // than the scale up. + if (signedCoefficientBAbs < scale) { + scale = 1e75; + adjustExponent = 75; + } + uint256 signedCoefficientAbs = mulDiv(signedCoefficientAAbs, scale, signedCoefficientBAbs); + signedCoefficient = (signedCoefficientA ^ signedCoefficientB) < 0 + ? -int256(signedCoefficientAbs) + : int256(signedCoefficientAbs); + } + + // Keep the exponent calculation outside the unchecked block so that we + // don't silently under/overflow. + int256 exponent = exponentA - exponentB - adjustExponent; + return (signedCoefficient, exponent); + } + + /// mulDiv as seen in Open Zeppelin, PRB Math, Solady, and other libraries. + /// Credit to Remco Bloemen under MIT license: https://2π.com/21/muldiv + function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { + // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use + // use the Chinese Remainder Theorem to reconstruct the 512-bit result. The result is stored in two 256 + // variables such that product = prod1 * 2^256 + prod0. + uint256 prod0; // Least significant 256 bits of the product + uint256 prod1; // Most significant 256 bits of the product + assembly ("memory-safe") { + let mm := mulmod(x, y, not(0)) + prod0 := mul(x, y) + prod1 := sub(sub(mm, prod0), lt(mm, prod0)) + } + + // Handle non-overflow cases, 256 by 256 division. + if (prod1 == 0) { + unchecked { + return prod0 / denominator; + } + } + + // Make sure the result is less than 2^256. Also prevents denominator == 0. + if (prod1 >= denominator) { + revert MulDivOverflow(x, y, denominator); + } + + //////////////////////////////////////////////////////////////////////////// + // 512 by 256 division + //////////////////////////////////////////////////////////////////////////// + + // Make division exact by subtracting the remainder from [prod1 prod0]. + uint256 remainder; + assembly ("memory-safe") { + // Compute remainder using the mulmod Yul instruction. + remainder := mulmod(x, y, denominator) + + // Subtract 256 bit number from 512-bit number. + prod1 := sub(prod1, gt(remainder, prod0)) + prod0 := sub(prod0, remainder) + } + + unchecked { + // Calculate the largest power of two divisor of the denominator using the unary operator ~. This operation cannot overflow + // because the denominator cannot be zero at this point in the function execution. The result is always >= 1. + // For more detail, see https://cs.stackexchange.com/q/138556/92363. + uint256 lpotdod = denominator & (~denominator + 1); + uint256 flippedLpotdod; + + assembly ("memory-safe") { + // Factor powers of two out of denominator. + // slither-disable-next-line divide-before-multiply + denominator := div(denominator, lpotdod) + + // Divide [prod1 prod0] by lpotdod. + // slither-disable-next-line divide-before-multiply + prod0 := div(prod0, lpotdod) + + // Get the flipped value `2^256 / lpotdod`. If the `lpotdod` is zero, the flipped value is one. + // `sub(0, lpotdod)` produces the two's complement version of `lpotdod`, which is equivalent to flipping all the bits. + // However, `div` interprets this value as an unsigned value: https://ethereum.stackexchange.com/q/147168/24693 + flippedLpotdod := add(div(sub(0, lpotdod), lpotdod), 1) + } + + // Shift in bits from prod1 into prod0. + prod0 |= prod1 * flippedLpotdod; + + // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such + // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for + // four bits. That is, denominator * inv = 1 mod 2^4. + // slither-disable-next-line incorrect-exp + uint256 inverse = (3 * denominator) ^ 2; + + // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works + // in modular arithmetic, doubling the correct bits in each step. + inverse *= 2 - denominator * inverse; // inverse mod 2^8 + inverse *= 2 - denominator * inverse; // inverse mod 2^16 + inverse *= 2 - denominator * inverse; // inverse mod 2^32 + inverse *= 2 - denominator * inverse; // inverse mod 2^64 + inverse *= 2 - denominator * inverse; // inverse mod 2^128 + inverse *= 2 - denominator * inverse; // inverse mod 2^256 + + // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. + // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is + // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 + // is no longer required. + result = prod0 * inverse; } } @@ -367,14 +503,9 @@ library LibDecimalFloatImplementation { return signedCoefficientA == signedCoefficientB; } - /// Inverts a float. Equivalent to `1 / x` with modest gas optimizations. + /// Inverts a float. Equivalent to `1 / x`. function inv(int256 signedCoefficient, int256 exponent) internal pure returns (int256, int256) { - (signedCoefficient, exponent) = normalize(signedCoefficient, exponent); - - signedCoefficient = 1e76 / signedCoefficient; - exponent = -exponent - 76; - - return (signedCoefficient, exponent); + return div(1e76, -76, signedCoefficient, exponent); } /// log10(x) for a float x. diff --git a/test/lib/LibCommonResults.sol b/test/lib/LibCommonResults.sol index 753bb4dc..0f209286 100644 --- a/test/lib/LibCommonResults.sol +++ b/test/lib/LibCommonResults.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: CAL pragma solidity ^0.8.25; -int256 constant ONES = 111111111111111111111111111111111111111; -int256 constant THREES = 333333333333333333333333333333333333333; +int256 constant ONES = 1111111111111111111111111111111111111111111111111111111111111111111111111111; +int256 constant THREES_PACKED = 3333333333333333333333333333333333333333333333333333333333333333333; +int256 constant THREES = 3333333333333333333333333333333333333333333333333333333333333333333333333333; diff --git a/test/src/lib/LibDecimalFloat.mixed.t.sol b/test/src/lib/LibDecimalFloat.mixed.t.sol index 4df03423..ba0c9789 100644 --- a/test/src/lib/LibDecimalFloat.mixed.t.sol +++ b/test/src/lib/LibDecimalFloat.mixed.t.sol @@ -2,7 +2,7 @@ pragma solidity =0.8.25; import {LibDecimalFloat, Float} from "src/lib/LibDecimalFloat.sol"; -import {THREES, ONES} from "../../lib/LibCommonResults.sol"; +import {THREES_PACKED, ONES} from "../../lib/LibCommonResults.sol"; import {Test} from "forge-std/Test.sol"; @@ -10,18 +10,18 @@ contract LibDecimalFloatMixedTest is Test { using LibDecimalFloat for Float; /// (1 / 3) * 555e18 - function testDiv1Over3() external pure { + function testDiv1Over3Mixed() external pure { Float a = LibDecimalFloat.packLossless(1, 0); Float b = LibDecimalFloat.packLossless(3, 0); Float c = a.div(b); (int256 signedCoefficientDiv, int256 exponentDiv) = LibDecimalFloat.unpack(c); - assertEq(signedCoefficientDiv, THREES, "coefficient"); - assertEq(exponentDiv, -39, "exponent"); + assertEq(signedCoefficientDiv, THREES_PACKED, "coefficient"); + assertEq(exponentDiv, -67, "exponent"); Float d = c.mul(LibDecimalFloat.packLossless(555, 18)); (int256 signedCoefficientMul, int256 exponentMul) = LibDecimalFloat.unpack(d); - assertEq(signedCoefficientMul, 184999999999999999999999999999999999999815); - assertEq(exponentMul, -21); + assertEq(signedCoefficientMul, 1849999999999999999999999999999999999999999999999999999999999999999); + assertEq(exponentMul, -46); } } diff --git a/test/src/lib/LibDecimalFloat.pow.t.sol b/test/src/lib/LibDecimalFloat.pow.t.sol index f4a6dcd7..4f356254 100644 --- a/test/src/lib/LibDecimalFloat.pow.t.sol +++ b/test/src/lib/LibDecimalFloat.pow.t.sol @@ -38,9 +38,15 @@ contract LibDecimalFloatPowTest is LogTest { } function testPows() external { - checkPow(5e37, -38, 3e37, -36, 9.32835820895522388059701492537313432835e38, -48); - checkPow(5e37, -38, 6e37, -36, 8.71080139372822299651567944250871080139e38, -57); - // // Issues found in fuzzing from here. + // 0.5 ^ 30 = 9.3132257e-10 + checkPow( + 5e37, -38, 3e37, -36, 9.328358208955223880597014925373134328358208955223880597014925373134e66, -66 - 10 + ); + // 0.5 ^ 60 = 8.6736174e-19 + checkPow( + 5e37, -38, 6e37, -36, 8.710801393728222996515679442508710801393728222996515679442508710801e66, -66 - 19 + ); + // Issues found in fuzzing from here. checkPow(99999, 0, 12182, 0, 1000, 60907); checkPow(1785215562, 0, 18, 0, 3388, 163); } diff --git a/test/src/lib/LibDecimalFloat.pow10.t.sol b/test/src/lib/LibDecimalFloat.pow10.t.sol index 60bf6a5d..960d8657 100644 --- a/test/src/lib/LibDecimalFloat.pow10.t.sol +++ b/test/src/lib/LibDecimalFloat.pow10.t.sol @@ -27,6 +27,12 @@ contract LibDecimalFloatPow10Test is LogTest { } else { Float floatPower10 = this.pow10External(float); (int256 signedCoefficientUnpacked, int256 exponentUnpacked) = floatPower10.unpack(); + + // Compensate for the implied pack and unpack. + (Float resultPacked, bool lossless) = LibDecimalFloat.packLossy(signedCoefficient, exponent); + (lossless); + (signedCoefficient, exponent) = resultPacked.unpack(); + assertEq(signedCoefficient, signedCoefficientUnpacked); assertEq(exponent, exponentUnpacked); } diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol index 2f3f3357..cb5f454d 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol @@ -40,12 +40,12 @@ contract LibDecimalFloatImplementationDivTest is Test { /// 1 / 3 function testDiv1Over3() external pure { - checkDiv(1, 0, 3, 0, THREES, -39); + checkDiv(1, 0, 3, 0, THREES, -76); } /// - 1 / 3 function testDivNegative1Over3() external pure { - checkDiv(-1, 0, 3, 0, -THREES, -39); + checkDiv(-1, 0, 3, 0, -THREES, -76); } /// 1 / 3 gas @@ -56,22 +56,22 @@ contract LibDecimalFloatImplementationDivTest is Test { /// 1e18 / 3 function testDiv1e18Over3() external pure { - checkDiv(1e18, 0, 3, 0, THREES, -21); + checkDiv(1e18, 0, 3, 0, THREES, -58); } /// 10,0 / 1e38,-37 == 1 function testDivTenOverOOMs() external pure { - checkDiv(10, 0, 1e38, -37, 1e39, -39); + checkDiv(10, 0, 1e38, -37, 1e76, -76); } /// 1e38,-37 / 2,0 == 5 function testDivOOMsOverTen() external pure { - checkDiv(1e38, -37, 2, 0, 5e38, -38); + checkDiv(1e38, -37, 2, 0, 5e75, -75); } /// 5e37,-37 / 2e37,-37 == 2.5 function testDivOOMs5and2() external pure { - checkDiv(5e37, -37, 2e37, -37, 25e38, -39); + checkDiv(5e37, -37, 2e37, -37, 2.5e76, -76); } /// (1 / 9) / (1 / 3) == 0.333.. @@ -79,18 +79,24 @@ contract LibDecimalFloatImplementationDivTest is Test { // 1 / 9 (int256 signedCoefficientA, int256 exponentA) = LibDecimalFloatImplementation.div(1, 0, 9, 0); assertEq(signedCoefficientA, ONES); - assertEq(exponentA, -39); + assertEq(exponentA, -76); // 1 / 3 (int256 signedCoefficientB, int256 exponentB) = LibDecimalFloatImplementation.div(1, 0, 3, 0); assertEq(signedCoefficientB, THREES); - assertEq(exponentB, -39); + assertEq(exponentB, -76); // (1 / 9) / (1 / 3) (int256 signedCoefficient, int256 exponent) = LibDecimalFloatImplementation.div(signedCoefficientA, exponentA, signedCoefficientB, exponentB); - assertEq(signedCoefficient, 333333333333333333333333333333333333336); - assertEq(exponent, -39); + assertEq(signedCoefficient, THREES); + assertEq(exponent, -76); + + // (1 / 3) / (1 / 9) == 3 + (signedCoefficient, exponent) = + LibDecimalFloatImplementation.div(signedCoefficientB, exponentB, signedCoefficientA, exponentA); + assertEq(signedCoefficient, 3e76); + assertEq(exponent, -76); } /// forge-config: default.fuzz.runs = 100 @@ -102,7 +108,7 @@ contract LibDecimalFloatImplementationDivTest is Test { int256 di = 0; while (true) { int256 i = 1; - int256 j = -39 - di; + int256 j = -76 - di; while (true) { // want to see full precision on the THREES regardless of the // scale of the numerator and denominator. diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.inv.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.inv.t.sol index 2a46baf5..b1a4be20 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.inv.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.inv.t.sol @@ -6,10 +6,16 @@ import {LibDecimalFloatSlow} from "test/lib/LibDecimalFloatSlow.sol"; import { LibDecimalFloatImplementation, EXPONENT_MIN, - EXPONENT_MAX + EXPONENT_MAX, + MulDivOverflow } from "src/lib/implementation/LibDecimalFloatImplementation.sol"; contract LibDecimalFloatImplementationInvTest is Test { + function invExternal(int256 signedCoefficient, int256 exponent) external pure returns (int256, int256) { + (signedCoefficient, exponent) = LibDecimalFloatImplementation.inv(signedCoefficient, exponent); + return (signedCoefficient, exponent); + } + /// Compare reference. function testInvReference(int256 signedCoefficient, int256 exponent) external pure { vm.assume(signedCoefficient != 0); @@ -33,4 +39,9 @@ contract LibDecimalFloatImplementationInvTest is Test { (int256 outputSignedCoefficient, int256 outputExponent) = LibDecimalFloatSlow.invSlow(3e37, -37); (outputSignedCoefficient, outputExponent); } + + function testInv0() external { + vm.expectRevert(abi.encodeWithSelector(MulDivOverflow.selector, 1e76, 1e75, 0)); + this.invExternal(0, 0); + } } diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.pow10.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.pow10.t.sol index de9c7ca3..5324d6ec 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.pow10.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.pow10.t.sol @@ -32,7 +32,7 @@ contract LibDecimalFloatImplementationPow10Test is LogTest { checkPow10(1, 4, 1000, 9997); } - function testExactLookups() external { + function testExactLookupsPow10() external { // 10^2 = 100 checkPow10(2, 0, 1000, -1); // 10^3 = 1000 @@ -56,7 +56,8 @@ contract LibDecimalFloatImplementationPow10Test is LogTest { checkPow10(0.5e37, -37, 3162, -3); checkPow10(0.3e37, -37, 1995, -3); - checkPow10(-0.3e37, -37, 0.501253132832080200501253132832080200501e39, -39); + // 10^-0.3 = 0.50118723362 + checkPow10(-0.3e37, -37, 0.5012531328320802005012531328320802005012531328320802005012531328320802005012e76, -76); } function testInterpolatedLookupsPower() external {