diff --git a/.gas-snapshot b/.gas-snapshot index 7f6ecb84..9350e800 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,187 +1,190 @@ -DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5104, μ: 2743074, ~: 2743016) -DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5104, μ: 2747129, ~: 2747212) -DecimalFloatCeilTest:testCeilDeployed(bytes32) (runs: 5104, μ: 2743105, ~: 2742729) -DecimalFloatConstantsTest:testEDeployed() (gas: 2742259) -DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2742291) -DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2742249) -DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2742224) -DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2742203) -DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5104, μ: 2749019, ~: 2749102) -DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5104, μ: 2743459, ~: 2743384) -DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5104, μ: 2742912, ~: 2742727) -DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5104, μ: 2747070, ~: 2746892) -DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5104, μ: 2743303, ~: 2743287) -DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5104, μ: 2743854, ~: 2743791) -DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5104, μ: 2744344, ~: 2744261) -DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5104, μ: 2743401, ~: 2743326) -DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5104, μ: 2743387, ~: 2743312) -DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5104, μ: 2747886, ~: 2747923) -DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5104, μ: 2742569, ~: 2742569) -DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5104, μ: 2743378, ~: 2743303) -DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5104, μ: 2743431, ~: 2743356) -DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5104, μ: 2743439, ~: 2743378) -DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5104, μ: 2743460, ~: 2743398) -DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5104, μ: 2743174, ~: 2743174) -DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5104, μ: 2747034, ~: 2747843) -DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5104, μ: 158769, ~: 158769) -DecimalFloatParseTest:testParseDeployed(string) (runs: 5104, μ: 2745806, ~: 2745675) -DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5104, μ: 2755926, ~: 2753551) -DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5104, μ: 2755575, ~: 2754253) -DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5104, μ: 2747478, ~: 2747512) -DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5104, μ: 2744480, ~: 2744374) -DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5104, μ: 2744618, ~: 2744903) -LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5104, μ: 5121, ~: 5121) -LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5104, μ: 10475, ~: 10702) -LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5104, μ: 9641, ~: 9392) +DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5098, μ: 2654875, ~: 2654817) +DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5098, μ: 2658941, ~: 2659013) +DecimalFloatCeilTest:testCeilDeployed(bytes32) (runs: 5098, μ: 2654903, ~: 2654530) +DecimalFloatConstantsTest:testEDeployed() (gas: 2654060) +DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 2654092) +DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 2654050) +DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 2654025) +DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 2654004) +DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5098, μ: 2660874, ~: 2660957) +DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5098, μ: 2655259, ~: 2655185) +DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5098, μ: 2654712, ~: 2654528) +DecimalFloatFormatTest:testFormatDeployed(bytes32) (runs: 5098, μ: 2658855, ~: 2658721) +DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5098, μ: 2655104, ~: 2655088) +DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5098, μ: 2655656, ~: 2655592) +DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5098, μ: 2656145, ~: 2656062) +DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5098, μ: 2655202, ~: 2655127) +DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5098, μ: 2655188, ~: 2655113) +DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5098, μ: 2659738, ~: 2659772) +DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5098, μ: 2654370, ~: 2654370) +DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5098, μ: 2655179, ~: 2655104) +DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5098, μ: 2655232, ~: 2655157) +DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5098, μ: 2655240, ~: 2655179) +DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5098, μ: 2655260, ~: 2655199) +DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5098, μ: 2654975, ~: 2654975) +DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5098, μ: 2658831, ~: 2659644) +DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5098, μ: 158769, ~: 158769) +DecimalFloatParseTest:testParseDeployed(string) (runs: 5098, μ: 2657608, ~: 2657477) +DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5098, μ: 2666894, ~: 2665819) +DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5098, μ: 2666573, ~: 2666521) +DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5098, μ: 2659288, ~: 2659313) +DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5098, μ: 2656303, ~: 2656175) +DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5098, μ: 2656436, ~: 2656704) +LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5098, μ: 5121, ~: 5121) +LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5098, μ: 10475, ~: 10702) +LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5098, μ: 9641, ~: 9392) LibDecimalFloatCeilTest:testCeilExamples() (gas: 30794) -LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5104, μ: 11040, ~: 10713) -LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5104, μ: 10059, ~: 9820) -LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5104, μ: 8961, ~: 9212) -LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5104, μ: 598, ~: 411) -LibDecimalFloatCeilTest:testCeilZero(int32) (runs: 5104, μ: 5438, ~: 5438) +LibDecimalFloatCeilTest:testCeilInRange(int224,int256) (runs: 5098, μ: 11040, ~: 10713) +LibDecimalFloatCeilTest:testCeilLessThanMin(int224,int256) (runs: 5098, μ: 10060, ~: 9820) +LibDecimalFloatCeilTest:testCeilNonNegative(int224,int256) (runs: 5098, μ: 8961, ~: 9212) +LibDecimalFloatCeilTest:testCeilNotReverts(bytes32) (runs: 5098, μ: 598, ~: 411) +LibDecimalFloatCeilTest:testCeilZero(int32) (runs: 5098, μ: 5438, ~: 5438) LibDecimalFloatConstantsTest:testFloatE() (gas: 3357) LibDecimalFloatConstantsTest:testFloatHalf() (gas: 3336) LibDecimalFloatConstantsTest:testFloatMaxNegativeValue() (gas: 3379) -LibDecimalFloatConstantsTest:testFloatMaxNegativeValueIsMax(bytes32) (runs: 5104, μ: 4488, ~: 4594) +LibDecimalFloatConstantsTest:testFloatMaxNegativeValueIsMax(bytes32) (runs: 5098, μ: 4488, ~: 4594) LibDecimalFloatConstantsTest:testFloatMaxPositiveValue() (gas: 3335) -LibDecimalFloatConstantsTest:testFloatMaxPositiveValueIsMax(bytes32) (runs: 5104, μ: 3545, ~: 3586) +LibDecimalFloatConstantsTest:testFloatMaxPositiveValueIsMax(bytes32) (runs: 5098, μ: 3545, ~: 3586) LibDecimalFloatConstantsTest:testFloatMinNegativeValue() (gas: 3335) -LibDecimalFloatConstantsTest:testFloatMinNegativeValueIsMin(bytes32) (runs: 5104, μ: 3496, ~: 3457) +LibDecimalFloatConstantsTest:testFloatMinNegativeValueIsMin(bytes32) (runs: 5098, μ: 3496, ~: 3457) LibDecimalFloatConstantsTest:testFloatMinPositiveValue() (gas: 3357) -LibDecimalFloatConstantsTest:testFloatMinPositiveValueIsMin(bytes32) (runs: 5104, μ: 4939, ~: 4870) +LibDecimalFloatConstantsTest:testFloatMinPositiveValueIsMin(bytes32) (runs: 5098, μ: 4938, ~: 4870) LibDecimalFloatConstantsTest:testFloatOne() (gas: 3358) LibDecimalFloatConstantsTest:testFloatTwo() (gas: 3380) LibDecimalFloatConstantsTest:testFloatZero() (gas: 3337) -LibDecimalFloatDecimalAddTest:testAddPacked(bytes32,bytes32) (runs: 5104, μ: 9762, ~: 9832) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5102, μ: 9615, ~: 9663) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5104, μ: 8130, ~: 8048) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5104, μ: 7452, ~: 7424) +LibDecimalFloatDecimalAddTest:testAddPacked(bytes32,bytes32) (runs: 5098, μ: 9762, ~: 9832) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5098, μ: 9615, ~: 9663) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5098, μ: 8130, ~: 8048) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5098, μ: 7452, ~: 7424) LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessFail() (gas: 4894) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPacked(bytes32,uint8) (runs: 5104, μ: 6717, ~: 6161) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5104, μ: 15805, ~: 15768) -LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5104, μ: 9274, ~: 9053) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPacked(bytes32,uint8) (runs: 5098, μ: 6718, ~: 6161) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5098, μ: 15805, ~: 15768) +LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5098, μ: 9110, ~: 9031) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyComplicated() (gas: 685958) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMax() (gas: 673506) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMaxPlusOne() (gas: 704362) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOne() (gas: 685936) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyMax() (gas: 673463) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOne() (gas: 686002) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOneMillion() (gas: 685937) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOverflow() (gas: 715261) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyPacked(uint256,uint8) (runs: 5104, μ: 9460, ~: 9374) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5104, μ: 5978, ~: 5937) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5104, μ: 7306, ~: 5860) -LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5099, μ: 16005, ~: 15996) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5104, μ: 14964, ~: 14729) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5104, μ: 10152, ~: 9811) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5104, μ: 10825, ~: 11076) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyPacked(bytes32,uint8) (runs: 5104, μ: 6803, ~: 6905) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5101, μ: 15348, ~: 15612) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5104, μ: 14493, ~: 14212) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncateLossless() (gas: 14523) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5104, μ: 13739, ~: 13602) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5104, μ: 4598, ~: 4598) -LibDecimalFloatDivTest:testDivPacked(bytes32,bytes32) (runs: 5104, μ: 11524, ~: 11603) -LibDecimalFloatEqTest:testEqPacked(bytes32,bytes32) (runs: 5104, μ: 5524, ~: 5450) -LibDecimalFloatEqTest:testEqXNotYExponents(bytes32,bytes32) (runs: 5104, μ: 4341, ~: 4234) -LibDecimalFloatEqTest:testEqZero(int32) (runs: 5104, μ: 5133, ~: 5133) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyPacked(uint256,uint8) (runs: 5098, μ: 9481, ~: 9396) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5098, μ: 5978, ~: 5937) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5098, μ: 6062, ~: 5860) +LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5097, μ: 15987, ~: 15862) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5098, μ: 14963, ~: 14729) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5098, μ: 10153, ~: 9811) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5098, μ: 10826, ~: 11076) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyPacked(bytes32,uint8) (runs: 5098, μ: 6803, ~: 6905) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5097, μ: 15348, ~: 15612) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5098, μ: 14492, ~: 14212) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncateLossless() (gas: 14500) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5098, μ: 13737, ~: 13602) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5098, μ: 4575, ~: 4575) +LibDecimalFloatDivTest:testDivByNegativeOneFloat(int224,int32) (runs: 5098, μ: 327534, ~: 326998) +LibDecimalFloatDivTest:testDivByOneFloat(int224,int32) (runs: 5098, μ: 303116, ~: 302160) +LibDecimalFloatDivTest:testDivPacked(bytes32,bytes32) (runs: 5098, μ: 11577, ~: 11667) +LibDecimalFloatEqTest:testEqPacked(bytes32,bytes32) (runs: 5098, μ: 5524, ~: 5450) +LibDecimalFloatEqTest:testEqXNotYExponents(bytes32,bytes32) (runs: 5098, μ: 4341, ~: 4234) +LibDecimalFloatEqTest:testEqZero(int32) (runs: 5098, μ: 5133, ~: 5133) LibDecimalFloatFloorTest:testFloorExamples() (gas: 38387) LibDecimalFloatFloorTest:testFloorGas0() (gas: 960) LibDecimalFloatFloorTest:testFloorGasTiny() (gas: 881) LibDecimalFloatFloorTest:testFloorGasZero() (gas: 553) -LibDecimalFloatFloorTest:testFloorInRange(int224,int256) (runs: 5104, μ: 11032, ~: 11044) -LibDecimalFloatFloorTest:testFloorLessThanMin(int224,int256) (runs: 5104, μ: 10284, ~: 10293) -LibDecimalFloatFloorTest:testFloorNonNegative(int224,int256) (runs: 5104, μ: 9547, ~: 9806) -LibDecimalFloatFloorTest:testFloorNotReverts(bytes32) (runs: 5104, μ: 461, ~: 365) +LibDecimalFloatFloorTest:testFloorInRange(int224,int256) (runs: 5098, μ: 11032, ~: 11044) +LibDecimalFloatFloorTest:testFloorLessThanMin(int224,int256) (runs: 5098, μ: 10284, ~: 10293) +LibDecimalFloatFloorTest:testFloorNonNegative(int224,int256) (runs: 5098, μ: 9547, ~: 9806) +LibDecimalFloatFloorTest:testFloorNotReverts(bytes32) (runs: 5098, μ: 461, ~: 365) LibDecimalFloatFracTest:testFracExamples() (gas: 39135) LibDecimalFloatFracTest:testFracGas0() (gas: 960) LibDecimalFloatFracTest:testFracGasTiny() (gas: 836) LibDecimalFloatFracTest:testFracGasZero() (gas: 820) -LibDecimalFloatFracTest:testFracInRange(int224,int256) (runs: 5104, μ: 10847, ~: 10859) -LibDecimalFloatFracTest:testFracLessThanMin(int224,int256) (runs: 5104, μ: 10273, ~: 10280) -LibDecimalFloatFracTest:testFracNonNegative(int224,int256) (runs: 5104, μ: 9806, ~: 10066) -LibDecimalFloatFracTest:testFracNotReverts(bytes32) (runs: 5104, μ: 630, ~: 621) +LibDecimalFloatFracTest:testFracInRange(int224,int256) (runs: 5098, μ: 10847, ~: 10859) +LibDecimalFloatFracTest:testFracLessThanMin(int224,int256) (runs: 5098, μ: 10273, ~: 10280) +LibDecimalFloatFracTest:testFracNonNegative(int224,int256) (runs: 5098, μ: 9806, ~: 10066) +LibDecimalFloatFracTest:testFracNotReverts(bytes32) (runs: 5098, μ: 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: 5104, μ: 3494, ~: 3494) -LibDecimalFloatGtTest:testGtReference(int224,int32,int224,int32) (runs: 5104, μ: 8066, ~: 6272) -LibDecimalFloatGtTest:testGtX(int224,int32) (runs: 5104, μ: 3882, ~: 3882) -LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int32,int32) (runs: 5104, μ: 10593, ~: 10332) -LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5104, μ: 11144, ~: 11349) -LibDecimalFloatGtTest:testGtXNotY(bytes32,bytes32) (runs: 5104, μ: 4341, ~: 4232) -LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int32,int256,int32) (runs: 5104, μ: 13764, ~: 13595) -LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int32,int32) (runs: 5104, μ: 10274, ~: 10026) -LibDecimalFloatGtTest:testGtZero(int32,int32) (runs: 5104, μ: 4793, ~: 4793) +LibDecimalFloatGtTest:testGtOneEAny(bytes32) (runs: 5098, μ: 3494, ~: 3494) +LibDecimalFloatGtTest:testGtReference(int224,int32,int224,int32) (runs: 5098, μ: 8068, ~: 6285) +LibDecimalFloatGtTest:testGtX(int224,int32) (runs: 5098, μ: 3882, ~: 3882) +LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int32,int32) (runs: 5098, μ: 10592, ~: 10332) +LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5098, μ: 11144, ~: 11349) +LibDecimalFloatGtTest:testGtXNotY(bytes32,bytes32) (runs: 5098, μ: 4341, ~: 4232) +LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int32,int256,int32) (runs: 5098, μ: 13764, ~: 13595) +LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int32,int32) (runs: 5098, μ: 10273, ~: 10026) +LibDecimalFloatGtTest:testGtZero(int32,int32) (runs: 5098, μ: 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: 5104, μ: 3494, ~: 3494) -LibDecimalFloatGteTest:testGteReference(int224,int32,int224,int32) (runs: 5104, μ: 8116, ~: 6344) -LibDecimalFloatGteTest:testGteX(int224,int32) (runs: 5104, μ: 3925, ~: 3925) -LibDecimalFloatGteTest:testGteXEAnyVsXEAny(int256,int32,int32) (runs: 5104, μ: 10622, ~: 10364) -LibDecimalFloatGteTest:testGteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5104, μ: 11156, ~: 11361) -LibDecimalFloatGteTest:testGteXNotLtY(bytes32,bytes32) (runs: 5104, μ: 3947, ~: 3873) -LibDecimalFloatGteTest:testGteXPositiveYNegative(int256,int32,int256,int32) (runs: 5104, μ: 13794, ~: 13623) -LibDecimalFloatGteTest:testGteXPositiveYZero(int256,int32,int32) (runs: 5104, μ: 9551, ~: 9170) -LibDecimalFloatGteTest:testGteZero(int32,int32) (runs: 5104, μ: 4838, ~: 4838) +LibDecimalFloatGteTest:testGteOneEAny(bytes32) (runs: 5098, μ: 3494, ~: 3494) +LibDecimalFloatGteTest:testGteReference(int224,int32,int224,int32) (runs: 5098, μ: 8117, ~: 6344) +LibDecimalFloatGteTest:testGteX(int224,int32) (runs: 5098, μ: 3925, ~: 3925) +LibDecimalFloatGteTest:testGteXEAnyVsXEAny(int256,int32,int32) (runs: 5098, μ: 10622, ~: 10364) +LibDecimalFloatGteTest:testGteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5098, μ: 11156, ~: 11361) +LibDecimalFloatGteTest:testGteXNotLtY(bytes32,bytes32) (runs: 5098, μ: 3947, ~: 3873) +LibDecimalFloatGteTest:testGteXPositiveYNegative(int256,int32,int256,int32) (runs: 5098, μ: 13794, ~: 13623) +LibDecimalFloatGteTest:testGteXPositiveYZero(int256,int32,int32) (runs: 5098, μ: 9551, ~: 9170) +LibDecimalFloatGteTest:testGteZero(int32,int32) (runs: 5098, μ: 4838, ~: 4838) LibDecimalFloatImplementationAddTest:testAdd123456789987654321() (gas: 4811) LibDecimalFloatImplementationAddTest:testAdd123456789e9987654321() (gas: 4861) -LibDecimalFloatImplementationAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5104, μ: 13101, ~: 13035) +LibDecimalFloatImplementationAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5098, μ: 13101, ~: 13034) LibDecimalFloatImplementationAddTest:testAddOneOneNotMaximized() (gas: 6148) LibDecimalFloatImplementationAddTest:testAddOneOnePreMaximized() (gas: 4300) LibDecimalFloatImplementationAddTest:testAddOneZero() (gas: 3666) -LibDecimalFloatImplementationAddTest:testAddSameExponent(int256,int256) (runs: 5104, μ: 6864, ~: 6935) +LibDecimalFloatImplementationAddTest:testAddSameExponent(int256,int256) (runs: 5097, μ: 6865, ~: 6935) LibDecimalFloatImplementationAddTest:testAddZero() (gas: 3665) -LibDecimalFloatImplementationAddTest:testAddZeroAnyExponent(int128) (runs: 5104, μ: 9293, ~: 9271) +LibDecimalFloatImplementationAddTest:testAddZeroAnyExponent(int128) (runs: 5098, μ: 9293, ~: 9271) LibDecimalFloatImplementationAddTest:testAddZeroOne() (gas: 3664) -LibDecimalFloatImplementationAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5102, μ: 13974, ~: 13948) +LibDecimalFloatImplementationAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5098, μ: 13974, ~: 13948) LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeExamples() (gas: 92086) -LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5098, μ: 16980, ~: 16963) +LibDecimalFloatImplementationAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5097, μ: 16980, ~: 16963) LibDecimalFloatImplementationAddTest:testGasAddOne() (gas: 1342) LibDecimalFloatImplementationAddTest:testGasAddZero() (gas: 360) -LibDecimalFloatImplementationAddTest:testOverflowChecks(int256,int256) (runs: 5104, μ: 3857, ~: 3843) +LibDecimalFloatImplementationAddTest:testOverflowChecks(int256,int256) (runs: 5098, μ: 3857, ~: 3843) LibDecimalFloatImplementationCharacteristicMantissaTest:testCharacteristicMantissaExamples() (gas: 30611) -LibDecimalFloatImplementationDivTest:testDiv1Over3() (gas: 7083) -LibDecimalFloatImplementationDivTest:testDiv1Over3Gas0() (gas: 2231) -LibDecimalFloatImplementationDivTest:testDiv1Over3Gas10() (gas: 19202) -LibDecimalFloatImplementationDivTest:testDiv1Over9Over1Over3() (gas: 14639) -LibDecimalFloatImplementationDivTest:testDiv1e18Over3() (gas: 6742) -LibDecimalFloatImplementationDivTest:testDivNegative1Over3() (gas: 7176) -LibDecimalFloatImplementationDivTest:testDivOOMs5and2() (gas: 6363) -LibDecimalFloatImplementationDivTest:testDivOOMsOverTen() (gas: 7053) -LibDecimalFloatImplementationDivTest:testDivTenOverOOMs() (gas: 6966) -LibDecimalFloatImplementationDivTest:testUnnormalizedThreesDiv0(int256,int256) (runs: 108, μ: 27290587, ~: 27290219) +LibDecimalFloatImplementationDivTest:testDiv1Over3() (gas: 7062) +LibDecimalFloatImplementationDivTest:testDiv1Over3Gas0() (gas: 2277) +LibDecimalFloatImplementationDivTest:testDiv1Over3Gas10() (gas: 19442) +LibDecimalFloatImplementationDivTest:testDiv1Over9Over1Over3() (gas: 14735) +LibDecimalFloatImplementationDivTest:testDiv1e18Over3() (gas: 6766) +LibDecimalFloatImplementationDivTest:testDivBy1(int256,int256) (runs: 5098, μ: 335339, ~: 339387) +LibDecimalFloatImplementationDivTest:testDivByNegativeOneFloat(int256,int256) (runs: 5098, μ: 337845, ~: 342152) +LibDecimalFloatImplementationDivTest:testDivNegative1Over3() (gas: 7157) +LibDecimalFloatImplementationDivTest:testDivOOMs5and2() (gas: 6387) +LibDecimalFloatImplementationDivTest:testDivOOMsOverTen() (gas: 7077) +LibDecimalFloatImplementationDivTest:testDivTenOverOOMs() (gas: 6990) +LibDecimalFloatImplementationDivTest:testUnnormalizedThreesDiv0(int256,int256) (runs: 102, μ: 27473206, ~: 27491668) 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: 5104, μ: 654, ~: 679) -LibDecimalFloatImplementationEqTest:testEqOneEAny(int256,int256) (runs: 5104, μ: 3416, ~: 3416) -LibDecimalFloatImplementationEqTest:testEqReference(int256,int256,int256,int256) (runs: 5104, μ: 9900, ~: 11437) -LibDecimalFloatImplementationEqTest:testEqX(int256) (runs: 5104, μ: 3392, ~: 3392) -LibDecimalFloatImplementationEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5103, μ: 4718, ~: 4714) -LibDecimalFloatImplementationEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5104, μ: 732, ~: 753) -LibDecimalFloatImplementationEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5104, μ: 3928, ~: 3953) -LibDecimalFloatImplementationEqTest:testEqZero(int256,int256) (runs: 5104, μ: 3440, ~: 3440) -LibDecimalFloatImplementationInvTest:testInv0() (gas: 5503) -LibDecimalFloatImplementationInvTest:testInvGas0() (gas: 2057) -LibDecimalFloatImplementationInvTest:testInvReference(int256,int256) (runs: 5103, μ: 14535, ~: 14484) -LibDecimalFloatImplementationInvTest:testInvSlowGas0() (gas: 2241) -LibDecimalFloatImplementationLog10Test:testExactLogs() (gas: 1263178) -LibDecimalFloatImplementationLog10Test:testExactLookupsLog10() (gas: 1280250) -LibDecimalFloatImplementationLog10Test:testInterpolatedLookups() (gas: 1260776) -LibDecimalFloatImplementationLog10Test:testSub1() (gas: 1257663) -LibDecimalFloatImplementationMaximizeTest:testMaximizedEverything(int256,int256) (runs: 5104, μ: 9478, ~: 9455) +LibDecimalFloatImplementationEqTest:testEqNotReverts(int256,int256,int256,int256) (runs: 5098, μ: 654, ~: 679) +LibDecimalFloatImplementationEqTest:testEqOneEAny(int256,int256) (runs: 5098, μ: 3416, ~: 3416) +LibDecimalFloatImplementationEqTest:testEqReference(int256,int256,int256,int256) (runs: 5098, μ: 9903, ~: 11446) +LibDecimalFloatImplementationEqTest:testEqX(int256) (runs: 5098, μ: 3392, ~: 3392) +LibDecimalFloatImplementationEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5098, μ: 4718, ~: 4714) +LibDecimalFloatImplementationEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5098, μ: 732, ~: 753) +LibDecimalFloatImplementationEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5098, μ: 3928, ~: 3953) +LibDecimalFloatImplementationEqTest:testEqZero(int256,int256) (runs: 5098, μ: 3440, ~: 3440) +LibDecimalFloatImplementationInvTest:testInv0() (gas: 5527) +LibDecimalFloatImplementationInvTest:testInvGas0() (gas: 2081) +LibDecimalFloatImplementationInvTest:testInvReference(int256,int256) (runs: 5098, μ: 14577, ~: 14532) +LibDecimalFloatImplementationInvTest:testInvSlowGas0() (gas: 2265) +LibDecimalFloatImplementationLog10Test:testExactLogs() (gas: 1265623) +LibDecimalFloatImplementationLog10Test:testExactLookupsLog10() (gas: 1301555) +LibDecimalFloatImplementationLog10Test:testInterpolatedLookups() (gas: 1260156) +LibDecimalFloatImplementationLog10Test:testSub1() (gas: 1262032) +LibDecimalFloatImplementationMaximizeTest:testMaximizedEverything(int256,int256) (runs: 5098, μ: 9478, ~: 9455) LibDecimalFloatImplementationMaximizeTest:testMaximizedExamples() (gas: 165819) -LibDecimalFloatImplementationMaximizeTest:testMaximizedIdempotent(int256,int256) (runs: 5104, μ: 9903, ~: 9868) -LibDecimalFloatImplementationMaximizeTest:testMaximizedReference(int256,int256) (runs: 5104, μ: 13375, ~: 14263) -LibDecimalFloatImplementationMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5104, μ: 12949, ~: 12929) +LibDecimalFloatImplementationMaximizeTest:testMaximizedIdempotent(int256,int256) (runs: 5098, μ: 9903, ~: 9868) +LibDecimalFloatImplementationMaximizeTest:testMaximizedReference(int256,int256) (runs: 5098, μ: 13377, ~: 14267) +LibDecimalFloatImplementationMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5098, μ: 12949, ~: 12929) LibDecimalFloatImplementationMulTest:testMul123456789987654321() (gas: 5559) -LibDecimalFloatImplementationMulTest:testMul123456789987654321WithExponents(int128,int128) (runs: 5104, μ: 15077, ~: 15160) +LibDecimalFloatImplementationMulTest:testMul123456789987654321WithExponents(int128,int128) (runs: 5098, μ: 15078, ~: 15160) LibDecimalFloatImplementationMulTest:testMul1_3979_0_5() (gas: 6193) LibDecimalFloatImplementationMulTest:testMul1e181e19() (gas: 5603) LibDecimalFloatImplementationMulTest:testMulGasOne() (gas: 1470) @@ -189,104 +192,100 @@ LibDecimalFloatImplementationMulTest:testMulGasZero() (gas: 325) LibDecimalFloatImplementationMulTest:testMulMaxSignedCoefficient() (gas: 6674) LibDecimalFloatImplementationMulTest:testMulNegativeOne() (gas: 5660) LibDecimalFloatImplementationMulTest:testMulNegativeOneOne() (gas: 5659) -LibDecimalFloatImplementationMulTest:testMulNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5104, μ: 15244, ~: 14593) +LibDecimalFloatImplementationMulTest:testMulNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5098, μ: 15244, ~: 14593) LibDecimalFloatImplementationMulTest:testMulOneNegativeOne() (gas: 5635) LibDecimalFloatImplementationMulTest:testMulOneOne() (gas: 5582) LibDecimalFloatImplementationMulTest:testMulOneZero() (gas: 4481) LibDecimalFloatImplementationMulTest:testMulZero0Exponent() (gas: 4503) -LibDecimalFloatImplementationMulTest:testMulZeroAnyExponent(int64,int64) (runs: 5104, μ: 4704, ~: 4704) +LibDecimalFloatImplementationMulTest:testMulZeroAnyExponent(int64,int64) (runs: 5098, μ: 4704, ~: 4704) LibDecimalFloatImplementationMulTest:testMulZeroOne() (gas: 4438) -LibDecimalFloatImplementationNormalizeTest:testExamples() (gas: 160899) -LibDecimalFloatImplementationNormalizeTest:testIdempotent(int256,int256) (runs: 5104, μ: 9875, ~: 9808) -LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5104, μ: 3533, ~: 3539) -LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5104, μ: 9415, ~: 9348) -LibDecimalFloatImplementationPow10Test:testExactLookupsPow10() (gas: 1283140) +LibDecimalFloatImplementationPow10Test:testExactLookupsPow10() (gas: 1283164) LibDecimalFloatImplementationPow10Test:testExactPows() (gas: 1260107) -LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1285366) -LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 5102, μ: 1259276, ~: 1259675) -LibDecimalFloatImplementationSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5104, μ: 15802, ~: 15834) -LibDecimalFloatImplementationSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5104, μ: 14990, ~: 14932) +LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1285510) +LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 5098, μ: 1259368, ~: 1259107) +LibDecimalFloatImplementationSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5098, μ: 15801, ~: 15834) +LibDecimalFloatImplementationSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5098, μ: 14991, ~: 14932) LibDecimalFloatImplementationSubTest:testSubOneFromMax() (gas: 6517) -LibDecimalFloatImplementationSubTest:testSubSelf(int224,int32) (runs: 5104, μ: 5509, ~: 5620) -LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyMixedAB(uint256,uint256,uint256,int256) (runs: 5104, μ: 9961, ~: 9888) -LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyMixedABOverflow(uint256,uint256,uint256,int256) (runs: 5104, μ: 11207, ~: 11200) -LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyMixedBA(uint256,uint256,uint256,int256) (runs: 5104, μ: 11205, ~: 11198) -LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyMixedBAOverflow(uint256,uint256,int256) (runs: 5104, μ: 9070, ~: 9018) -LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyNegative(uint256,uint256,uint256,int256) (runs: 5104, μ: 9968, ~: 9892) -LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyNegativeOverflow(uint256,uint256,uint256,int256) (runs: 5104, μ: 11200, ~: 11190) -LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyPositive(uint256,uint256,uint256,int256) (runs: 5104, μ: 9102, ~: 9033) -LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyPositiveOverflow(uint256,uint256,uint256,int256) (runs: 5104, μ: 11089, ~: 11086) +LibDecimalFloatImplementationSubTest:testSubSelf(int224,int32) (runs: 5098, μ: 5510, ~: 5620) +LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyMixedAB(uint256,uint256,uint256,int256) (runs: 5098, μ: 9961, ~: 9888) +LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyMixedABOverflow(uint256,uint256,uint256,int256) (runs: 5098, μ: 11207, ~: 11200) +LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyMixedBA(uint256,uint256,uint256,int256) (runs: 5098, μ: 11205, ~: 11198) +LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyMixedBAOverflow(uint256,uint256,int256) (runs: 5098, μ: 9071, ~: 9018) +LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyNegative(uint256,uint256,uint256,int256) (runs: 5098, μ: 9968, ~: 9892) +LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyNegativeOverflow(uint256,uint256,uint256,int256) (runs: 5098, μ: 11200, ~: 11190) +LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyPositive(uint256,uint256,uint256,int256) (runs: 5098, μ: 9103, ~: 9033) +LibDecimalFloatImplementationUnabsUnsignedMulOrDivLossyTest:testUnabsUnsignedMulOrDivLossyPositiveOverflow(uint256,uint256,uint256,int256) (runs: 5098, μ: 11090, ~: 11086) LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentExamples() (gas: 13429) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5099, μ: 14426, ~: 14395) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5104, μ: 13307, ~: 13527) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5104, μ: 11669, ~: 11718) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5104, μ: 3676, ~: 3676) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5101, μ: 13874, ~: 13665) -LibDecimalFloatInvTest:testInvMem(bytes32) (runs: 5104, μ: 10557, ~: 10616) -LibDecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5104, μ: 3899, ~: 3899) -LibDecimalFloatIsZeroTest:testIsZeroEqZero(bytes32) (runs: 5104, μ: 3527, ~: 3527) -LibDecimalFloatIsZeroTest:testIsZeroExamples(int32) (runs: 5104, μ: 4477, ~: 4477) -LibDecimalFloatIsZeroTest:testNotIsZero(int224,int32) (runs: 5103, μ: 3896, ~: 3896) -LibDecimalFloatLog10Test:testLog10Packed(bytes32) (runs: 5104, μ: 1651924, ~: 1271911) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5097, μ: 14426, ~: 14395) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5098, μ: 13307, ~: 13527) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5098, μ: 11669, ~: 11718) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5098, μ: 3676, ~: 3676) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5097, μ: 13874, ~: 13665) +LibDecimalFloatInvTest:testInvMem(bytes32) (runs: 5098, μ: 10606, ~: 10628) +LibDecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5098, μ: 3899, ~: 3899) +LibDecimalFloatIsZeroTest:testIsZeroEqZero(bytes32) (runs: 5098, μ: 3527, ~: 3527) +LibDecimalFloatIsZeroTest:testIsZeroExamples(int32) (runs: 5098, μ: 4477, ~: 4477) +LibDecimalFloatIsZeroTest:testNotIsZero(int224,int32) (runs: 5098, μ: 3896, ~: 3896) +LibDecimalFloatLog10Test:testLog10Packed(bytes32) (runs: 5098, μ: 1646641, ~: 1270121) 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: 5104, μ: 13750, ~: 13593) -LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int32,int32) (runs: 5104, μ: 10790, ~: 11008) -LibDecimalFloatLtTest:testLtOneEAny(int224,int32) (runs: 5104, μ: 3905, ~: 3905) -LibDecimalFloatLtTest:testLtReference(bytes32,bytes32) (runs: 5104, μ: 4697, ~: 4998) -LibDecimalFloatLtTest:testLtVsEqualVsGt(bytes32,bytes32) (runs: 5104, μ: 4323, ~: 4210) -LibDecimalFloatLtTest:testLtX(int224) (runs: 5104, μ: 3798, ~: 3798) -LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int32,int32) (runs: 5104, μ: 10558, ~: 10297) -LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5104, μ: 11154, ~: 11359) -LibDecimalFloatLtTest:testLtZero(int32,int32) (runs: 5104, μ: 4171, ~: 4171) +LibDecimalFloatLtTest:testLtNegativeVsPositive(int256,int32,int256,int32) (runs: 5098, μ: 13750, ~: 13593) +LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int32,int32) (runs: 5098, μ: 10790, ~: 11008) +LibDecimalFloatLtTest:testLtOneEAny(int224,int32) (runs: 5098, μ: 3905, ~: 3905) +LibDecimalFloatLtTest:testLtReference(bytes32,bytes32) (runs: 5098, μ: 4697, ~: 4998) +LibDecimalFloatLtTest:testLtVsEqualVsGt(bytes32,bytes32) (runs: 5098, μ: 4323, ~: 4210) +LibDecimalFloatLtTest:testLtX(int224) (runs: 5098, μ: 3798, ~: 3798) +LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int32,int32) (runs: 5098, μ: 10557, ~: 10297) +LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5098, μ: 11153, ~: 11359) +LibDecimalFloatLtTest:testLtZero(int32,int32) (runs: 5098, μ: 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: 5104, μ: 3493, ~: 3493) -LibDecimalFloatLteTest:testLteReference(int224,int32,int224,int32) (runs: 5104, μ: 8112, ~: 6328) -LibDecimalFloatLteTest:testLteX(int224,int32) (runs: 5104, μ: 3904, ~: 3904) -LibDecimalFloatLteTest:testLteXEAnyVsXEAny(int256,int32,int32) (runs: 5104, μ: 10582, ~: 10321) -LibDecimalFloatLteTest:testLteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5104, μ: 11177, ~: 11383) -LibDecimalFloatLteTest:testLteXNotLtY(bytes32,bytes32) (runs: 5104, μ: 3882, ~: 3807) -LibDecimalFloatLteTest:testLteXPositiveYNegative(int256,int32,int256,int32) (runs: 5104, μ: 13102, ~: 12931) -LibDecimalFloatLteTest:testLteXPositiveYZero(int256,int32,int32) (runs: 5104, μ: 9575, ~: 9191) -LibDecimalFloatLteTest:testLteZero(int32,int32) (runs: 5104, μ: 4816, ~: 4816) -LibDecimalFloatMaxTest:testMaxX(bytes32) (runs: 5104, μ: 4246, ~: 4246) -LibDecimalFloatMaxTest:testMaxXY(bytes32,bytes32) (runs: 5104, μ: 4689, ~: 4613) -LibDecimalFloatMaxTest:testMaxXYEqual(bytes32) (runs: 5104, μ: 5272, ~: 5272) -LibDecimalFloatMaxTest:testMaxXYGreater(bytes32,bytes32) (runs: 5096, μ: 6129, ~: 6016) -LibDecimalFloatMaxTest:testMaxXYLess(bytes32,bytes32) (runs: 5104, μ: 6141, ~: 6027) -LibDecimalFloatMinTest:testMinX(bytes32) (runs: 5104, μ: 4268, ~: 4268) -LibDecimalFloatMinTest:testMinXY(bytes32,bytes32) (runs: 5104, μ: 4689, ~: 4613) -LibDecimalFloatMinTest:testMinXYEqual(bytes32) (runs: 5104, μ: 5292, ~: 5292) -LibDecimalFloatMinTest:testMinXYGreater(bytes32,bytes32) (runs: 5096, μ: 6074, ~: 5961) -LibDecimalFloatMinTest:testMinXYLess(bytes32,bytes32) (runs: 5104, μ: 6087, ~: 5972) -LibDecimalFloatMinusTest:testMinusPacked(bytes32) (runs: 5104, μ: 5550, ~: 5550) -LibDecimalFloatMixedTest:testDiv1Over3Mixed() (gas: 11039) -LibDecimalFloatMulTest:testMulPacked(bytes32,bytes32) (runs: 5104, μ: 9630, ~: 10369) -LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5104, μ: 5352, ~: 5352) -LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5104, μ: 1645674, ~: 1256407) -LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5104, μ: 1248482, ~: 1248447) -LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 5099, μ: 1246471, ~: 1246471) -LibDecimalFloatPowTest:testPowAZeroNegative(bytes32) (runs: 5101, μ: 1246870, ~: 1246870) -LibDecimalFloatPowTest:testPowBZero(bytes32,int32) (runs: 5104, μ: 1246058, ~: 1246058) -LibDecimalFloatPowTest:testPows() (gas: 1315564) -LibDecimalFloatPowTest:testRoundTripFuzzPow(bytes32,bytes32) (runs: 5104, μ: 1262566, ~: 1260242) -LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1535140) -LibDecimalFloatSqrtTest:testRoundTripFuzzSqrt(int224,int32) (runs: 5104, μ: 1295391, ~: 1294787) -LibDecimalFloatSqrtTest:testSqrt() (gas: 1293719) -LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5104, μ: 1248098, ~: 1248059) -LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1417956) -LibDecimalFloatSubTest:testSubPacked(bytes32,bytes32) (runs: 5104, μ: 9974, ~: 9995) +LibDecimalFloatLteTest:testLteOneEAny(bytes32) (runs: 5098, μ: 3493, ~: 3493) +LibDecimalFloatLteTest:testLteReference(int224,int32,int224,int32) (runs: 5098, μ: 8113, ~: 6341) +LibDecimalFloatLteTest:testLteX(int224,int32) (runs: 5098, μ: 3904, ~: 3904) +LibDecimalFloatLteTest:testLteXEAnyVsXEAny(int256,int32,int32) (runs: 5098, μ: 10582, ~: 10321) +LibDecimalFloatLteTest:testLteXEAnyVsXEAnyNegative(int256,int32,int32) (runs: 5098, μ: 11177, ~: 11383) +LibDecimalFloatLteTest:testLteXNotLtY(bytes32,bytes32) (runs: 5098, μ: 3882, ~: 3807) +LibDecimalFloatLteTest:testLteXPositiveYNegative(int256,int32,int256,int32) (runs: 5098, μ: 13102, ~: 12931) +LibDecimalFloatLteTest:testLteXPositiveYZero(int256,int32,int32) (runs: 5098, μ: 9575, ~: 9191) +LibDecimalFloatLteTest:testLteZero(int32,int32) (runs: 5098, μ: 4816, ~: 4816) +LibDecimalFloatMaxTest:testMaxX(bytes32) (runs: 5098, μ: 4246, ~: 4246) +LibDecimalFloatMaxTest:testMaxXY(bytes32,bytes32) (runs: 5098, μ: 4689, ~: 4613) +LibDecimalFloatMaxTest:testMaxXYEqual(bytes32) (runs: 5098, μ: 5272, ~: 5272) +LibDecimalFloatMaxTest:testMaxXYGreater(bytes32,bytes32) (runs: 5097, μ: 6129, ~: 6016) +LibDecimalFloatMaxTest:testMaxXYLess(bytes32,bytes32) (runs: 5097, μ: 6141, ~: 6027) +LibDecimalFloatMinTest:testMinX(bytes32) (runs: 5098, μ: 4268, ~: 4268) +LibDecimalFloatMinTest:testMinXY(bytes32,bytes32) (runs: 5098, μ: 4689, ~: 4613) +LibDecimalFloatMinTest:testMinXYEqual(bytes32) (runs: 5098, μ: 5292, ~: 5292) +LibDecimalFloatMinTest:testMinXYGreater(bytes32,bytes32) (runs: 5097, μ: 6074, ~: 5961) +LibDecimalFloatMinTest:testMinXYLess(bytes32,bytes32) (runs: 5097, μ: 6087, ~: 5972) +LibDecimalFloatMinusTest:testMinusPacked(bytes32) (runs: 5098, μ: 5550, ~: 5550) +LibDecimalFloatMixedTest:testDiv1Over3Mixed() (gas: 11063) +LibDecimalFloatMulTest:testMulPacked(bytes32,bytes32) (runs: 5098, μ: 9630, ~: 10369) +LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5098, μ: 5352, ~: 5352) +LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5098, μ: 1646622, ~: 1256455) +LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5098, μ: 1247476, ~: 1247586) +LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 5096, μ: 1246471, ~: 1246471) +LibDecimalFloatPowTest:testPowAZeroNegative(bytes32) (runs: 5097, μ: 1246870, ~: 1246870) +LibDecimalFloatPowTest:testPowBZero(bytes32,int32) (runs: 5098, μ: 1246058, ~: 1246058) +LibDecimalFloatPowTest:testPows() (gas: 1310306) +LibDecimalFloatPowTest:testRoundTripFuzzPow(bytes32,bytes32) (runs: 5098, μ: 1261918, ~: 1258607) +LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1597986) +LibDecimalFloatSqrtTest:testRoundTripFuzzSqrt(int224,int32) (runs: 5098, μ: 1295710, ~: 1299383) +LibDecimalFloatSqrtTest:testSqrt() (gas: 1291880) +LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5098, μ: 1247095, ~: 1247204) +LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1415022) +LibDecimalFloatSubTest:testSubPacked(bytes32,bytes32) (runs: 5098, μ: 9974, ~: 9995) LibFormatDecimalFloatTest:testFormatDecimalExamples() (gas: 133439) -LibFormatDecimalFloatTest:testFormatDecimalRoundTrip(uint256) (runs: 5104, μ: 25221, ~: 20105) -LibFormatDecimalFloatTest:testFormatDecimalRoundTripNegative(int256) (runs: 5104, μ: 19680, ~: 21006) +LibFormatDecimalFloatTest:testFormatDecimalRoundTrip(uint256) (runs: 5098, μ: 25221, ~: 20105) +LibFormatDecimalFloatTest:testFormatDecimalRoundTripNegative(int256) (runs: 5098, μ: 19678, ~: 21006) LibLogTableBytesTest:testToBytesAntiLogTableDec() (gas: 159794) LibLogTableBytesTest:testToBytesAntiLogTableDecSmall() (gas: 162322) LibLogTableBytesTest:testToBytesLogTableDec() (gas: 143165) @@ -308,7 +307,7 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatEDot() (gas: 4190) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert5() (gas: 4176) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert6() (gas: 4188) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponents() (gas: 402635) -LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5104, μ: 45895, ~: 37386) +LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5098, μ: 45903, ~: 37386) LibParseDecimalFloatTest:testParseLiteralDecimalFloatLeadingZeros() (gas: 59779) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeE() (gas: 6100) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeFrac() (gas: 5137) @@ -316,5 +315,5 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert0() (gas: 27 LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert1() (gas: 24801) LibParseDecimalFloatTest:testParseLiteralDecimalFloatSpecific() (gas: 22959) LibParseDecimalFloatTest:testParseLiteralDecimalFloatUnrelated() (gas: 50856) -LibParseDecimalFloatTest:testParsePacked(string) (runs: 5104, μ: 9786, ~: 9668) -TestDecimalFloatUnpackTest:testUnpackDeployed(bytes32) (runs: 5104, μ: 158422, ~: 158422) \ No newline at end of file +LibParseDecimalFloatTest:testParsePacked(string) (runs: 5098, μ: 9787, ~: 9668) +TestDecimalFloatUnpackTest:testUnpackDeployed(bytes32) (runs: 5098, μ: 158422, ~: 158422) \ No newline at end of file diff --git a/src/lib/LibDecimalFloat.sol b/src/lib/LibDecimalFloat.sol index d59b9f2a..aef82101 100644 --- a/src/lib/LibDecimalFloat.sol +++ b/src/lib/LibDecimalFloat.sol @@ -20,24 +20,12 @@ import { } from "../error/ErrDecimalFloat.sol"; import { LibDecimalFloatImplementation, - NORMALIZED_ZERO_SIGNED_COEFFICIENT, - NORMALIZED_ZERO_EXPONENT, - NORMALIZED_MIN, - NORMALIZED_MAX, - EXPONENT_STEP_SIZE, - SIGNED_NORMALIZED_MAX, EXPONENT_MAX, EXPONENT_MIN } from "./implementation/LibDecimalFloatImplementation.sol"; type Float is bytes32; -/// @dev When normalizing a number, how far we "leap" when very far from -/// normalized. -int256 constant EXPONENT_LEAP_SIZE = 24; -/// @dev The multiplier for the leap size, calculated at compile time. -int256 constant EXPONENT_LEAP_MULTIPLIER = int256(uint256(10 ** uint256(EXPONENT_LEAP_SIZE))); - /// @title LibDecimalFloat /// Floating point math library for Rainlang. /// Broadly implements decimal floating point math with 224 signed bits for the @@ -60,32 +48,10 @@ int256 constant EXPONENT_LEAP_MULTIPLIER = int256(uint256(10 ** uint256(EXPONENT /// fraction. This technically results in less precision than a binary floating /// point system, but is much more predictable and easier to reason about in the /// context of financial inputs and outputs, which are typically all decimal -/// values as understood by humans. However, consider that we have 127 bits of +/// values as understood by humans. However, consider that we have 224 bits of /// precision in the coefficient, which is far more than the 53 bits of a double /// precision floating point number regardless of binary/decimal considerations, /// and should be more than enough for most defi use cases. -/// -/// A typical defi fixed point value has 18 decimals, while a normalized decimal -/// float in this system has 37 decimals. This means, for example, that we can -/// represent the entire supply of any 18 decimal fixed point token amount up to -/// 10 quintillion tokens, without any loss of precision. -/// -/// One use case for this number system is representing ratios of tokens that -/// have both large differences in their decimals and unit value. For example, -/// at the time of writing, 1 SHIB is worth about 2.7e-10 BTC while the -/// WBTC contract only supports 8 decimals vs. SHIB's 18 decimals. It's literally -/// not possible to represent a purchase of 1 SHIB (1e18) worth of WBTC, so it's -/// easy to see how a fixed point decimal system could accidentally round -/// something down to `0` or up to `1` or similarly bad precision loss, simply -/// due to the large difference in OOMs in _representation_ of any two tokens -/// being considered. -/// -/// Of course there are workarounds, such as temporarily inflating values during -/// calculations and rescaling them afterwards, but they are ad-hoc and error -/// prone. Importantly, the workarounds are typically not obvious to the target -/// demographic of Rainlang, and it is not obvious where/when they need to be -/// applied without rigourous testing/mathematical models that are beyond the -/// scope of the typical user of Rainlang. library LibDecimalFloat { using LibDecimalFloat for Float; @@ -323,13 +289,6 @@ library LibDecimalFloat { /// Pack a signed coefficient and exponent into a single `PackedFloat`. /// Clearly this involves fitting 64 bytes into 32 bytes, so there will be /// data loss. - /// Normalized numbers are guaranteed to round trip through pack/unpack in - /// a lossless manner. The normalization process will _truncate_ on precision - /// loss if required, which is significantly better than potentially - /// _decapitating_ a non-normalized number during the pack operation. It is - /// highly recomended to normalize numbers before packing them. - /// Note that mathematical operations in this lib all output normalized - /// so typically this is implicit. /// @param signedCoefficient The signed coefficient of the floating point /// representation. /// @param exponent The exponent of the floating point representation. @@ -377,8 +336,7 @@ library LibDecimalFloat { } /// Unpack a packed bytes32 into a signed coefficient and exponent. This is - /// the inverse of `pack`. Note that the unpacked values are not necessarily - /// normalized, especially if their provenance is unknown or user input. + /// the inverse of `pack`. /// @param float The packed representation of the signed coefficient and /// exponent. /// @return signedCoefficient The signed coefficient of the floating point @@ -410,7 +368,7 @@ library LibDecimalFloat { return c; } - /// Subtract two floats together as a normalized result. + /// Subtract float a from float b. /// /// This is effectively shorthand for adding the two floats with the second /// float negated. Therefore, the same caveats apply as for `add`. @@ -525,7 +483,6 @@ library LibDecimalFloat { (int256 signedCoefficient, int256 exponent) = float.unpack(); (signedCoefficient, exponent) = LibDecimalFloatImplementation.inv(signedCoefficient, exponent); (Float result, bool lossless) = packLossy(signedCoefficient, exponent); - // Inversion cannot be lossy as long as the denominator is normalized. (lossless); return result; } @@ -544,8 +501,6 @@ library LibDecimalFloat { /// Numeric less than for floats. /// A float is less than another if its numeric value is less than the other. /// For example, 1e2 is less than 1e3, and 1e2 is less than 2e2. - /// Any representable value can be compared without precision loss, e.g. no - /// normalization is done internally. /// @param a The first float to compare. /// @param b The second float to compare. function lt(Float a, Float b) internal pure returns (bool) { @@ -560,8 +515,6 @@ library LibDecimalFloat { /// Numeric greater than for floats. /// A float is greater than another if its numeric value is greater than the /// other. For example, 1e3 is greater than 1e2, and 2e2 is greater than 1e2. - /// Any representable value can be compared without precision loss, e.g. no - /// normalization is done internally. /// @param a The first float to compare. /// @param b The second float to compare. function gt(Float a, Float b) internal pure returns (bool) { diff --git a/src/lib/implementation/LibDecimalFloatImplementation.sol b/src/lib/implementation/LibDecimalFloatImplementation.sol index ff0a3f8b..5679170a 100644 --- a/src/lib/implementation/LibDecimalFloatImplementation.sol +++ b/src/lib/implementation/LibDecimalFloatImplementation.sol @@ -16,9 +16,9 @@ error WithTargetExponentOverflow(int256 signedCoefficient, int256 exponent, int2 uint256 constant ADD_MAX_EXPONENT_DIFF = 76; -/// @dev The maximum exponent that can be normalized. +/// @dev The maximum exponent that can be maximized. /// This is crazy large, so should never be a problem for any real use case. -/// We need it to guard against overflow when normalizing. +/// We need it to guard against overflow when maximizing. int256 constant EXPONENT_MAX = type(int256).max / 2; int256 constant EXPONENT_MAX_PLUS_ONE = EXPONENT_MAX + 1; @@ -27,43 +27,15 @@ int256 constant EXPONENT_MAX_PLUS_ONE = EXPONENT_MAX + 1; /// We need it to guard against overflow when normalizing. int256 constant EXPONENT_MIN = -EXPONENT_MAX; -/// @dev When normalizing a number, how far we "step" when close to normalized. -int256 constant EXPONENT_STEP_SIZE = 1; -/// @dev The multiplier for the step size, calculated at compile time. -int256 constant EXPONENT_STEP_MULTIPLIER = int256(uint256(10 ** uint256(EXPONENT_STEP_SIZE))); -/// @dev When normalizing a number, how far we "jump" when somewhat far from -/// normalized. -int256 constant EXPONENT_JUMP_SIZE = 6; -/// @dev The multiplier for the jump size, calculated at compile time. -int256 constant PRECISION_JUMP_MULTIPLIER = int256(uint256(10 ** uint256(EXPONENT_JUMP_SIZE))); -/// @dev Every value above or equal to this can jump down while normalizing -/// without overshooting and causing unnecessary precision loss. -int256 constant NORMALIZED_JUMP_DOWN_THRESHOLD = SIGNED_NORMALIZED_MAX * PRECISION_JUMP_MULTIPLIER; -/// @dev Every value below this can jump up while normalizing without -/// overshooting the normalized range. -int256 constant NORMALIZED_JUMP_UP_THRESHOLD = SIGNED_NORMALIZED_MIN / PRECISION_JUMP_MULTIPLIER; - -/// @dev The minimum absolute value of a normalized signed coefficient. -uint256 constant NORMALIZED_MIN = 1e37; -int256 constant SIGNED_NORMALIZED_MIN = 1e37; -/// @dev The maximum absolute value of a normalized signed coefficient. -uint256 constant NORMALIZED_MAX = 1e38 - 1; -int256 constant SIGNED_NORMALIZED_MAX = 1e38 - 1; -uint256 constant NORMALIZED_MAX_PLUS_ONE = 1e38; -int256 constant SIGNED_NORMALIZED_MAX_PLUS_ONE = 1e38; - -/// @dev The signed coefficient of zero when normalized. -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; +int256 constant MAXIMIZED_ZERO_SIGNED_COEFFICIENT = 0; /// @dev The exponent of maximized zero. -int256 constant MAXIMIZED_ZERO_EXPONENT = NORMALIZED_ZERO_EXPONENT; +int256 constant MAXIMIZED_ZERO_EXPONENT = 0; + +int256 constant LOG10_Y_EXPONENT = -76; library LibDecimalFloatImplementation { - /// Negates and normalizes a float. + /// Negates a float. /// Equivalent to `0 - x`. /// /// https://speleotrove.com/decimal/daops.html#refplusmin @@ -543,7 +515,6 @@ library LibDecimalFloatImplementation { /// For example, 1e2, 10e1, and 100e0 are all equal. Also implies that 0eX /// and 0eY are equal for all X and Y. /// Any representable value can be equality checked without precision loss, - /// e.g. no normalization is done internally. /// @param signedCoefficientA The signed coefficient of the first floating /// point number. /// @param exponentA The exponent of the first floating point number. @@ -585,8 +556,6 @@ library LibDecimalFloatImplementation { { unchecked { { - (signedCoefficient, exponent) = normalize(signedCoefficient, exponent); - if (signedCoefficient <= 0) { if (signedCoefficient == 0) { revert Log10Zero(); @@ -594,25 +563,35 @@ library LibDecimalFloatImplementation { revert Log10Negative(signedCoefficient, exponent); } } + (signedCoefficient, exponent) = maximize(signedCoefficient, exponent); } - // This is a positive log. i.e. log(x) where x >= 1. - if (exponent > -38) { - // This is an exact power of 10. - if (signedCoefficient == 1e37) { - return (exponent + 37, 0); - } + // all powers of 10 look like 1 with a different exponent + if (signedCoefficient == 1e76) { + return (exponent + 76, 0); + } + bool isAtLeastE76 = signedCoefficient >= 1e76; + // This is a positive log. i.e. log(x) where x >= 1. + if (exponent >= (isAtLeastE76 ? -76 : -75)) { int256 y1Coefficient; int256 y2Coefficient; int256 x1Coefficient; int256 x2Coefficient; - int256 x1Exponent = exponent; - bool interpolate; + // exact powers of 10 are already caught above. + // but e.g. 20 would be 2e76, -75 and true for isAtLeastE76 + // => adding exp 76 yields 1, which is the correct result. + // 200 would be 2e76, -74 and true for isAtLeastE76 + // => adding exp 76 yields 2, which is the correct result. + // however 90 would be 9e75, -74 and false for isAtLeastE76 + // => adding exp 75 yields 1, which is the correct result. + // 900 would be 9e75, -73 and false for isAtLeastE76 + // => adding exp 75 yields 2, which is the correct result. + int256 powerOfTen = exponent + int256(isAtLeastE76 ? int256(76) : int256(75)); // Table lookup. { - uint256 scale = 1e34; + int256 scale = 1e72; assembly ("memory-safe") { //slither-disable-next-line divide-before-multiply function lookupTableVal(tables, index) -> result { @@ -639,6 +618,11 @@ library LibDecimalFloatImplementation { result := add(result, mload(0)) } + // Need to increase the scale by one OOM here so that the + // signed coefficient has 4 digits always, to make it + // easy to calculate the idx. + if isAtLeastE76 { scale := mul(scale, 10) } + // Truncate the signed coefficient to what we can look // up in the table. // Slither false positive because the truncation is @@ -647,30 +631,45 @@ library LibDecimalFloatImplementation { x1Coefficient := div(signedCoefficient, scale) let idx := sub(x1Coefficient, 1000) x1Coefficient := mul(x1Coefficient, scale) + // Technically we only need to do this if we need to + // interpolate but it's cheaper to just do an `add` + // unconditionally than pay for an `if` and often also + // do the `add`. x2Coefficient := add(x1Coefficient, scale) - interpolate := iszero(eq(x1Coefficient, signedCoefficient)) - y1Coefficient := mul(scale, lookupTableVal(tablesDataContract, idx)) + // If we don't bring the scale back down here we can get + // overflows when multiplying the output of the lookups. + // We are reusing the same scale variable to avoid a + // compiler stack overflow. + // Slither false positive here, this division is simply + // the inverse of the mul above. + //slither-disable-next-line divide-before-multiply + if isAtLeastE76 { scale := div(scale, 10) } - if interpolate { y2Coefficient := mul(scale, lookupTableVal(tablesDataContract, add(idx, 1))) } + y1Coefficient := mul(scale, lookupTableVal(tablesDataContract, idx)) + // Only do the second lookup if we expect interpolation + // to need it. + if iszero(eq(x1Coefficient, signedCoefficient)) { + y2Coefficient := mul(scale, lookupTableVal(tablesDataContract, add(idx, 1))) + } } } - if (interpolate) { - (signedCoefficient, exponent) = unitLinearInterpolation( - x1Coefficient, signedCoefficient, x2Coefficient, exponent, y1Coefficient, y2Coefficient, -38 - ); - } else { - signedCoefficient = y1Coefficient; - exponent = -38; - } - - return add(signedCoefficient, exponent, x1Exponent + 37, 0); + (signedCoefficient, exponent) = unitLinearInterpolation( + x1Coefficient, + signedCoefficient, + x2Coefficient, + exponent, + y1Coefficient, + y2Coefficient, + LOG10_Y_EXPONENT + ); + return add(signedCoefficient, exponent, powerOfTen, 0); } // This is a negative log. i.e. log(x) where 0 < x < 1. // log(x) = -log(1/x) else { - (signedCoefficient, exponent) = div(1e37, -37, signedCoefficient, exponent); + (signedCoefficient, exponent) = inv(signedCoefficient, exponent); (signedCoefficient, exponent) = log10(tablesDataContract, signedCoefficient, exponent); return minus(signedCoefficient, exponent); } @@ -778,83 +777,6 @@ library LibDecimalFloatImplementation { } } - function isNormalized(int256 signedCoefficient, int256 exponent) internal pure returns (bool) { - bool result; - uint256 normalizedMaxPlusOne = NORMALIZED_MAX_PLUS_ONE; - uint256 normalizedMin = NORMALIZED_MIN; - assembly { - result := - or( - and( - iszero(sdiv(signedCoefficient, normalizedMaxPlusOne)), - iszero(iszero(sdiv(signedCoefficient, normalizedMin))) - ), - and(iszero(signedCoefficient), iszero(exponent)) - ) - } - return result; - } - - function normalize(int256 signedCoefficient, int256 exponent) internal pure returns (int256, int256) { - unchecked { - if (isNormalized(signedCoefficient, exponent)) { - return (signedCoefficient, exponent); - } - - if (signedCoefficient == 0) { - return (NORMALIZED_ZERO_SIGNED_COEFFICIENT, NORMALIZED_ZERO_EXPONENT); - } - - if (exponent / EXPONENT_MAX_PLUS_ONE != 0) { - revert ExponentOverflow(signedCoefficient, exponent); - } - - if (signedCoefficient / SIGNED_NORMALIZED_MAX_PLUS_ONE != 0) { - if (signedCoefficient / 1e56 != 0) { - signedCoefficient /= 1e19; - exponent += 19; - } - - if (signedCoefficient / 1e46 != 0) { - signedCoefficient /= 1e9; - exponent += 9; - } - - while (signedCoefficient / 1e39 != 0) { - signedCoefficient /= 100; - exponent += 2; - } - - if (signedCoefficient / 1e38 != 0) { - signedCoefficient /= 10; - exponent += 1; - } - } else { - if (signedCoefficient / 1e18 == 0) { - signedCoefficient *= 1e19; - exponent -= 19; - } - - if (signedCoefficient / 1e28 == 0) { - signedCoefficient *= 1e9; - exponent -= 9; - } - - while (signedCoefficient / 1e36 == 0) { - signedCoefficient *= 100; - exponent -= 2; - } - - if (signedCoefficient / 1e37 == 0) { - signedCoefficient *= 10; - exponent -= 1; - } - } - - return (signedCoefficient, exponent); - } - } - /// Rescale two floats so that they are possible to directly compare using /// standard operators on the signed coefficient. /// @@ -973,7 +895,7 @@ library LibDecimalFloatImplementation { } else if (targetExponent > exponent) { int256 exponentDiff = targetExponent - exponent; if (exponentDiff > 76 || exponentDiff < 0) { - return (NORMALIZED_ZERO_SIGNED_COEFFICIENT); + return (MAXIMIZED_ZERO_SIGNED_COEFFICIENT); } return signedCoefficient / int256(10 ** uint256(exponentDiff)); @@ -1077,6 +999,10 @@ library LibDecimalFloatImplementation { int256 y2Coefficient, int256 yExponent ) internal pure returns (int256, int256) { + // Short circuit if the amount of interpolation is 0. + if (xCoefficient == x1Coefficient) { + return (y1Coefficient, yExponent); + } int256 numeratorSignedCoefficient; int256 numeratorExponent; diff --git a/test/src/lib/LibDecimalFloat.decimal.t.sol b/test/src/lib/LibDecimalFloat.decimal.t.sol index f67c7df4..7b126d8d 100644 --- a/test/src/lib/LibDecimalFloat.decimal.t.sol +++ b/test/src/lib/LibDecimalFloat.decimal.t.sol @@ -2,14 +2,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd pragma solidity =0.8.25; -import { - LibDecimalFloat, - ExponentOverflow, - NORMALIZED_MAX, - NORMALIZED_MIN, - NegativeFixedDecimalConversion, - Float -} from "src/lib/LibDecimalFloat.sol"; +import {LibDecimalFloat, ExponentOverflow, NegativeFixedDecimalConversion, Float} from "src/lib/LibDecimalFloat.sol"; import {LibDecimalFloatImplementation} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; import {Test, console2, stdError} from "forge-std/Test.sol"; @@ -60,7 +53,7 @@ contract LibDecimalFloatDecimalTest is Test { /// Round trip from/to decimal values without precision loss function testFixedDecimalRoundTripLossless(uint256 value, uint8 decimals) external pure { - value = bound(value, 0, uint256(NORMALIZED_MAX)); + value = uint256(bound(value, 0, uint256(int256(type(int224).max)))); (int256 signedCoefficient, int256 exponent, bool lossless0) = LibDecimalFloat.fromFixedDecimalLossy(value, decimals); @@ -126,20 +119,10 @@ contract LibDecimalFloatDecimalTest is Test { } } - /// The max normalized value will be lossless. - function testFromFixedDecimalLossyNormalizedMax() external pure { + /// The max int256 value will be lossless because there is no packing. + function testFromFixedDecimalLossyMax() external pure { for (uint8 i = 0; i < type(uint8).max; i++) { - checkFromFixedDecimalLossless( - uint256(NORMALIZED_MAX), i, 99999999999999999999999999999999999999, -int256(uint256(i)) - ); - } - } - - /// The max normalized value + 1 will be lossless because the least - /// significant digit is 0. - function testFromFixedDecimalLossyNormalizedMaxPlusOne() external pure { - for (uint8 i = 0; i < type(uint8).max; i++) { - checkFromFixedDecimalLossless(uint256(NORMALIZED_MAX) + 1, i, 1e38, 0 - int256(uint256(i))); + checkFromFixedDecimalLossless(uint256(type(int256).max), i, type(int256).max, -int256(uint256(i))); } } @@ -154,7 +137,7 @@ contract LibDecimalFloatDecimalTest is Test { /// Any conversion where only 0 digits are truncated will be lossless. function testFromFixedDecimalLossyTruncateZero(uint256 value, uint8 decimals) external pure { uint256 scale = 0; - while (value > uint256(NORMALIZED_MAX)) { + while (value > type(uint224).max) { value /= 10; scale++; } diff --git a/test/src/lib/LibDecimalFloat.decimalLossless.t.sol b/test/src/lib/LibDecimalFloat.decimalLossless.t.sol index dff7b0f8..878610a3 100644 --- a/test/src/lib/LibDecimalFloat.decimalLossless.t.sol +++ b/test/src/lib/LibDecimalFloat.decimalLossless.t.sol @@ -4,8 +4,6 @@ pragma solidity =0.8.25; import { LibDecimalFloat, - SIGNED_NORMALIZED_MAX, - NORMALIZED_MAX, LossyConversionFromFloat, LossyConversionToFloat, Float diff --git a/test/src/lib/LibDecimalFloat.pow.t.sol b/test/src/lib/LibDecimalFloat.pow.t.sol index 3f4426cf..eb3bd3fc 100644 --- a/test/src/lib/LibDecimalFloat.pow.t.sol +++ b/test/src/lib/LibDecimalFloat.pow.t.sol @@ -31,8 +31,6 @@ contract LibDecimalFloatPowTest is LogTest { Float c = a.pow(b, tables); uint256 afterGas = gasleft(); console2.log("Gas used:", beforeGas - afterGas); - console2.logInt(signedCoefficientA); - console2.logInt(exponentA); (int256 actualSignedCoefficient, int256 actualExponent) = c.unpack(); assertEq(actualSignedCoefficient, expectedSignedCoefficient, "signedCoefficient"); assertEq(actualExponent, expectedExponent, "exponent"); @@ -66,11 +64,7 @@ contract LibDecimalFloatPowTest is LogTest { a = a.minus(); } (int256 signedCoefficientA, int256 exponentA) = a.unpack(); - (int256 signedCoefficientANormalized, int256 exponentANormalized) = - LibDecimalFloatImplementation.normalize(signedCoefficientA, exponentA); - vm.expectRevert( - abi.encodeWithSelector(Log10Negative.selector, signedCoefficientANormalized, exponentANormalized) - ); + vm.expectRevert(abi.encodeWithSelector(Log10Negative.selector, signedCoefficientA, exponentA)); this.powExternal(a, b); } diff --git a/test/src/lib/LibDecimalFloat.sqrt.t.sol b/test/src/lib/LibDecimalFloat.sqrt.t.sol index e71f2787..52703326 100644 --- a/test/src/lib/LibDecimalFloat.sqrt.t.sol +++ b/test/src/lib/LibDecimalFloat.sqrt.t.sol @@ -68,9 +68,7 @@ contract LibDecimalFloatSqrtTest is LogTest { address tables = logTables(); (int256 signedCoefficient, int256 exponent) = a.unpack(); - (int256 signedCoefficientNormalized, int256 exponentNormalized) = - LibDecimalFloatImplementation.normalize(signedCoefficient, exponent); - vm.expectRevert(abi.encodeWithSelector(Log10Negative.selector, signedCoefficientNormalized, exponentNormalized)); + vm.expectRevert(abi.encodeWithSelector(Log10Negative.selector, signedCoefficient, exponent)); this.sqrtExternal(a, tables); } diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol index eebc800a..855bc041 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.div.t.sol @@ -117,7 +117,7 @@ contract LibDecimalFloatImplementationDivTest is Test { } function testDivByNegativeOneFloat(int256 signedCoefficient, int256 exponent) external pure { - exponent = bound(exponent, type(int256).min + 76, type(int256).max); + exponent = bound(exponent, type(int256).min + 76, type(int256).max - 1); (int256 expectedCoefficient, int256 expectedExponent) = LibDecimalFloatImplementation.maximize(signedCoefficient, exponent); (expectedCoefficient, expectedExponent) = diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.log10.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.log10.t.sol index 8a57bb87..0006efc1 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.log10.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.log10.t.sol @@ -29,18 +29,24 @@ contract LibDecimalFloatImplementationLog10Test is LogTest { checkLog10(1000, 0, 3, 0); checkLog10(10000, 0, 4, 0); checkLog10(1e37, -37, 0, 0); + checkLog10(1e76, -76, 0, 0); } function testExactLookupsLog10() external { checkLog10(1001, 0, 3.0004e76, -76); checkLog10(100.1e1, -1, 2.0004e76, -76); checkLog10(10.01e2, -2, 1.0004e76, -76); - checkLog10(1.001e3, -3, 0.0004e38, -38); + checkLog10(1.001e3, -3, 0.0004e76, -76); checkLog10(10.02e2, -2, 1.0009e76, -76); checkLog10(10.99e2, -2, 1.0411e76, -76); checkLog10(6566, 0, 3.8173e76, -76); + + checkLog10(20, 0, 1.301e76, -76); + checkLog10(200, 0, 2.301e76, -76); + checkLog10(90, 0, 1.9542e76, -76); + checkLog10(900, 0, 2.9542e76, -76); } function testInterpolatedLookups() external { @@ -48,6 +54,8 @@ contract LibDecimalFloatImplementationLog10Test is LogTest { } function testSub1() external { - checkLog10(0.1001e4, -4, -0.9996e38, -38); + checkLog10(0.1001e4, -4, -0.9996e76, -76); + + checkLog10(0.5e1, -1, -0.301e76, -76); } } diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.mul.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.mul.t.sol index b073fab8..b536b7a1 100644 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.mul.t.sol +++ b/test/src/lib/implementation/LibDecimalFloatImplementation.mul.t.sol @@ -5,9 +5,7 @@ pragma solidity =0.8.25; import { LibDecimalFloatImplementation, EXPONENT_MIN, - EXPONENT_MAX, - NORMALIZED_ZERO_SIGNED_COEFFICIENT, - NORMALIZED_ZERO_EXPONENT + EXPONENT_MAX } from "src/lib/implementation/LibDecimalFloatImplementation.sol"; import {Test} from "forge-std/Test.sol"; import {LibDecimalFloatSlow} from "test/lib/LibDecimalFloatSlow.sol"; diff --git a/test/src/lib/implementation/LibDecimalFloatImplementation.normalize.t.sol b/test/src/lib/implementation/LibDecimalFloatImplementation.normalize.t.sol deleted file mode 100644 index 4d395a79..00000000 --- a/test/src/lib/implementation/LibDecimalFloatImplementation.normalize.t.sol +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-License-Identifier: LicenseRef-DCL-1.0 -// SPDX-FileCopyrightText: Copyright (c) 2020 Rain Open Source Software Ltd -pragma solidity =0.8.25; - -import {Test} from "forge-std/Test.sol"; - -import { - LibDecimalFloatImplementation, - EXPONENT_MIN, - EXPONENT_MAX -} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; -import {LibDecimalFloatImplementationSlow} from "../../../lib/implementation/LibDecimalFloatImplementationSlow.sol"; - -contract LibDecimalFloatImplementationNormalizeTest is Test { - /// isNormalized reference. - function testIsNormalizedReference(int256 signedCoefficient, int256 exponent) external pure { - bool expected = LibDecimalFloatImplementationSlow.isNormalizedSlow(signedCoefficient, exponent); - bool actual = LibDecimalFloatImplementation.isNormalized(signedCoefficient, exponent); - assertEq(actual, expected); - } - - /// Every normalized number is normalized. - function testNormalized(int256 signedCoefficient, int256 exponent) external pure { - exponent = bound(exponent, EXPONENT_MIN, EXPONENT_MAX); - (int256 actualSignedCoefficient, int256 actualExponent) = - LibDecimalFloatImplementation.normalize(signedCoefficient, exponent); - assertTrue(LibDecimalFloatImplementation.isNormalized(actualSignedCoefficient, actualExponent)); - } - - function checkNormalized( - int256 signedCoefficient, - int256 exponent, - int256 expectedCoefficient, - int256 expectedExponent - ) internal pure { - (int256 actualSignedCoefficient, int256 actualExponent) = - LibDecimalFloatImplementation.normalize(signedCoefficient, exponent); - assertEq(actualSignedCoefficient, expectedCoefficient); - assertEq(actualExponent, expectedExponent); - } - - function testExamples() external pure { - checkNormalized(0, 0, 0, 0); - checkNormalized(1e37, 0, 1e37, 0); - checkNormalized(type(int256).max, 0, 5.7896044618658097711785492504343953926e37, 39); - checkNormalized(type(int256).min, 0, -5.7896044618658097711785492504343953926e37, 39); - checkNormalized(42, 0, 42e36, -36); - checkNormalized(42e36, -36, 42e36, -36); - - for (int256 i = 76; i >= 0; i--) { - checkNormalized(int256(10 ** uint256(i)), 0, 1e37, i - 37); - } - } - - /// Normalization should be idempotent. - function testIdempotent(int256 signedCoefficient, int256 exponent) external pure { - exponent = bound(exponent, EXPONENT_MIN, EXPONENT_MAX); - (int256 normalizedSignedCoefficient, int256 normalizedExponent) = - LibDecimalFloatImplementation.normalize(signedCoefficient, exponent); - (int256 actualSignedCoefficient, int256 actualExponent) = - LibDecimalFloatImplementation.normalize(normalizedSignedCoefficient, normalizedExponent); - assertEq(actualSignedCoefficient, normalizedSignedCoefficient); - assertEq(actualExponent, normalizedExponent); - } -}