diff --git a/.gas-snapshot b/.gas-snapshot index ee2b4d0a..efbd2636 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,150 +1,183 @@ -LibDecimalFloatAbsTest:testAbsMinValue(int256) (runs: 5096, μ: 4405, ~: 4405) -LibDecimalFloatAbsTest:testAbsNegative(int256,int256) (runs: 5096, μ: 9362, ~: 9559) -LibDecimalFloatAbsTest:testAbsNonNegative(int256,int256) (runs: 5096, μ: 8590, ~: 8351) -LibDecimalFloatDecimalAddTest:testAdd123456789987654321() (gas: 4792) -LibDecimalFloatDecimalAddTest:testAdd123456789e9987654321() (gas: 4845) -LibDecimalFloatDecimalAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5096, μ: 12719, ~: 12558) -LibDecimalFloatDecimalAddTest:testAddOneOneNotNormalized() (gas: 5339) -LibDecimalFloatDecimalAddTest:testAddOneOnePreNormalized() (gas: 4241) -LibDecimalFloatDecimalAddTest:testAddOneZero() (gas: 3679) -LibDecimalFloatDecimalAddTest:testAddSameExponentSameCoefficient(int256,int256) (runs: 5096, μ: 5734, ~: 5782) -LibDecimalFloatDecimalAddTest:testAddZero() (gas: 3654) -LibDecimalFloatDecimalAddTest:testAddZeroAnyExponent(int128) (runs: 5096, μ: 8902, ~: 8892) -LibDecimalFloatDecimalAddTest:testAddZeroOne() (gas: 3677) -LibDecimalFloatDecimalAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5096, μ: 13524, ~: 13432) -LibDecimalFloatDecimalAddTest:testAddingSmallToLargeReturnsLargeExamples() (gas: 19203) -LibDecimalFloatDecimalAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5096, μ: 16584, ~: 16454) -LibDecimalFloatDecimalAddTest:testGasAddOne() (gas: 938) -LibDecimalFloatDecimalAddTest:testGasAddZero() (gas: 377) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5096, μ: 9227, ~: 9275) -LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5096, μ: 7293, ~: 7265) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessFail() (gas: 3855) -LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5096, μ: 14690, ~: 14643) -LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5096, μ: 8820, ~: 8598) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyComplicated() (gas: 600531) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMax() (gas: 588079) +LibDecimalFloatAbsTest:testAbsMem((int256,int256)) (runs: 5099, μ: 5950, ~: 5890) +LibDecimalFloatAbsTest:testAbsMinValue(int256) (runs: 5099, μ: 4405, ~: 4405) +LibDecimalFloatAbsTest:testAbsNegative(int256,int256) (runs: 5099, μ: 9370, ~: 9569) +LibDecimalFloatAbsTest:testAbsNonNegative(int256,int256) (runs: 5099, μ: 8570, ~: 8347) +LibDecimalFloatDecimalAddTest:testAdd123456789987654321() (gas: 4757) +LibDecimalFloatDecimalAddTest:testAdd123456789e9987654321() (gas: 4788) +LibDecimalFloatDecimalAddTest:testAddMem((int256,int256),(int256,int256)) (runs: 5099, μ: 6912, ~: 7245) +LibDecimalFloatDecimalAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5099, μ: 12675, ~: 12516) +LibDecimalFloatDecimalAddTest:testAddOneOneNotNormalized() (gas: 5349) +LibDecimalFloatDecimalAddTest:testAddOneOnePreNormalized() (gas: 4228) +LibDecimalFloatDecimalAddTest:testAddOneZero() (gas: 3634) +LibDecimalFloatDecimalAddTest:testAddSameExponentSameCoefficient(int256,int256) (runs: 5099, μ: 5700, ~: 5746) +LibDecimalFloatDecimalAddTest:testAddZero() (gas: 3632) +LibDecimalFloatDecimalAddTest:testAddZeroAnyExponent(int128) (runs: 5099, μ: 8902, ~: 8892) +LibDecimalFloatDecimalAddTest:testAddZeroOne() (gas: 3633) +LibDecimalFloatDecimalAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5099, μ: 13500, ~: 13410) +LibDecimalFloatDecimalAddTest:testAddingSmallToLargeReturnsLargeExamples() (gas: 19216) +LibDecimalFloatDecimalAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5098, μ: 16598, ~: 16454) +LibDecimalFloatDecimalAddTest:testGasAddOne() (gas: 947) +LibDecimalFloatDecimalAddTest:testGasAddZero() (gas: 399) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5099, μ: 9232, ~: 9281) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5099, μ: 4416, ~: 4423) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5099, μ: 7295, ~: 7266) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessFail() (gas: 3859) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessMem((int256,int256),uint8) (runs: 5099, μ: 6855, ~: 7838) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5099, μ: 14674, ~: 14633) +LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5099, μ: 8843, ~: 8620) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyComplicated() (gas: 600575) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyMem(uint256,uint8) (runs: 5099, μ: 5321, ~: 5318) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMax() (gas: 588036) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMaxPlusOne() (gas: 618935) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOne() (gas: 600509) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOneMillion() (gas: 600510) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOneMillion() (gas: 600532) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOverflow() (gas: 629579) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5096, μ: 5564, ~: 5525) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5096, μ: 7002, ~: 5537) -LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5096, μ: 14943, ~: 14883) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5096, μ: 13549, ~: 13322) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5096, μ: 9445, ~: 9214) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5096, μ: 9121, ~: 9323) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5096, μ: 12845, ~: 13054) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5096, μ: 13451, ~: 13229) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncateLossless() (gas: 13134) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5096, μ: 12488, ~: 12422) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5096, μ: 4346, ~: 4346) -LibDecimalFloatDivideTest:testDivide1Over3() (gas: 5724) -LibDecimalFloatDivideTest:testDivide1Over3Gas0() (gas: 755) -LibDecimalFloatDivideTest:testDivide1Over3Gas10() (gas: 6851) -LibDecimalFloatDivideTest:testDivide1Over9Over1Over3() (gas: 8894) -LibDecimalFloatDivideTest:testDivide1e18Over3() (gas: 5736) -LibDecimalFloatDivideTest:testDivideNegative1Over3() (gas: 5793) -LibDecimalFloatDivideTest:testDivideOOMs5and2() (gas: 4601) -LibDecimalFloatDivideTest:testDivideOOMsOverTen() (gas: 5427) -LibDecimalFloatDivideTest:testDivideTenOverOOMs() (gas: 5353) -LibDecimalFloatDivideTest:testUnnormalizedThreesDivision0(int256,int256) (runs: 100, μ: 19644358, ~: 19644589) -LibDecimalFloatEqTest:testEqGasAZero() (gas: 425) -LibDecimalFloatEqTest:testEqGasBZero() (gas: 468) -LibDecimalFloatEqTest:testEqGasBothZero() (gas: 445) -LibDecimalFloatEqTest:testEqGasDifferentSigns() (gas: 477) -LibDecimalFloatEqTest:testEqGasExponentDiffOverflow() (gas: 572) -LibDecimalFloatEqTest:testEqNotReverts(int256,int256,int256,int256) (runs: 5096, μ: 647, ~: 671) -LibDecimalFloatEqTest:testEqOneEAny(int256,int256) (runs: 5096, μ: 3410, ~: 3410) -LibDecimalFloatEqTest:testEqReference(int256,int256,int256,int256) (runs: 5096, μ: 9887, ~: 11434) -LibDecimalFloatEqTest:testEqX(int256) (runs: 5096, μ: 3384, ~: 3384) -LibDecimalFloatEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5096, μ: 4699, ~: 4697) -LibDecimalFloatEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5096, μ: 724, ~: 744) -LibDecimalFloatEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5096, μ: 3918, ~: 3942) -LibDecimalFloatEqTest:testEqXNotYExponents(int256,int256,int256,int256) (runs: 5096, μ: 4223, ~: 4299) -LibDecimalFloatEqTest:testEqZero(int256,int256) (runs: 5096, μ: 3432, ~: 3432) -LibDecimalFloatFloorTest:testFloorExamples() (gas: 27720) -LibDecimalFloatFloorTest:testFloorGas0() (gas: 475) -LibDecimalFloatFloorTest:testFloorGasTiny() (gas: 384) -LibDecimalFloatFloorTest:testFloorGasZero() (gas: 378) -LibDecimalFloatFloorTest:testFloorInRange(int256,int256) (runs: 5096, μ: 10082, ~: 10094) -LibDecimalFloatFloorTest:testFloorLessThanMin(int256,int256) (runs: 5096, μ: 9311, ~: 9486) -LibDecimalFloatFloorTest:testFloorNonNegative(int256,int256) (runs: 5096, μ: 8751, ~: 8530) -LibDecimalFloatFloorTest:testFloorNotReverts(int256,int256) (runs: 5096, μ: 472, ~: 461) -LibDecimalFloatFracTest:testFracExamples() (gas: 27680) -LibDecimalFloatFracTest:testFracGas0() (gas: 498) -LibDecimalFloatFracTest:testFracGasTiny() (gas: 407) -LibDecimalFloatFracTest:testFracGasZero() (gas: 389) -LibDecimalFloatFracTest:testFracInRange(int256,int256) (runs: 5096, μ: 9925, ~: 9937) -LibDecimalFloatFracTest:testFracLessThanMin(int256,int256) (runs: 5096, μ: 9268, ~: 9443) -LibDecimalFloatFracTest:testFracNonNegative(int256,int256) (runs: 5096, μ: 8729, ~: 8508) -LibDecimalFloatFracTest:testFracNotReverts(int256,int256) (runs: 5096, μ: 451, ~: 440) -LibDecimalFloatGtTest:testGtGasAZero() (gas: 424) -LibDecimalFloatGtTest:testGtGasBZero() (gas: 423) -LibDecimalFloatGtTest:testGtGasBothZero() (gas: 447) -LibDecimalFloatGtTest:testGtGasDifferentSigns() (gas: 425) -LibDecimalFloatGtTest:testGtGasExponentDiffOverflow() (gas: 572) -LibDecimalFloatGtTest:testGtOneEAny(int256,int256) (runs: 5096, μ: 3437, ~: 3437) -LibDecimalFloatGtTest:testGtReference(int256,int256,int256,int256) (runs: 5096, μ: 9893, ~: 11517) -LibDecimalFloatGtTest:testGtX(int256) (runs: 5096, μ: 3409, ~: 3409) -LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int256,int256) (runs: 5096, μ: 9284, ~: 9054) -LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int256,int256) (runs: 5096, μ: 9768, ~: 9961) -LibDecimalFloatGtTest:testGtXNotY(int256,int256,int256,int256) (runs: 5096, μ: 4189, ~: 4264) -LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int256,int256,int256) (runs: 5096, μ: 11904, ~: 11865) -LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int256,int256) (runs: 5096, μ: 9010, ~: 8783) -LibDecimalFloatGtTest:testGtZero(int256,int256) (runs: 5096, μ: 3457, ~: 3457) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5099, μ: 5589, ~: 5547) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5099, μ: 7031, ~: 5559) +LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5097, μ: 14946, ~: 14885) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5099, μ: 13526, ~: 13300) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5099, μ: 9466, ~: 9236) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyMem((int256,int256),uint8) (runs: 5099, μ: 6918, ~: 7893) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5099, μ: 9077, ~: 9278) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5098, μ: 12891, ~: 13099) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5099, μ: 13472, ~: 13252) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncateLossless() (gas: 13162) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5099, μ: 12420, ~: 12355) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5099, μ: 4368, ~: 4368) +LibDecimalFloatDivideTest:testDivide1Over3() (gas: 5642) +LibDecimalFloatDivideTest:testDivide1Over3Gas0() (gas: 673) +LibDecimalFloatDivideTest:testDivide1Over3Gas10() (gas: 6031) +LibDecimalFloatDivideTest:testDivide1Over9Over1Over3() (gas: 8648) +LibDecimalFloatDivideTest:testDivide1e18Over3() (gas: 5676) +LibDecimalFloatDivideTest:testDivideMem((int256,int256),(int256,int256)) (runs: 5099, μ: 8610, ~: 8838) +LibDecimalFloatDivideTest:testDivideNegative1Over3() (gas: 5722) +LibDecimalFloatDivideTest:testDivideOOMs5and2() (gas: 4519) +LibDecimalFloatDivideTest:testDivideOOMsOverTen() (gas: 5323) +LibDecimalFloatDivideTest:testDivideTenOverOOMs() (gas: 5316) +LibDecimalFloatDivideTest:testUnnormalizedThreesDivision0(int256,int256) (runs: 103, μ: 19158189, ~: 19158411) +LibDecimalFloatEqTest:testEqGasAZero() (gas: 405) +LibDecimalFloatEqTest:testEqGasBZero() (gas: 470) +LibDecimalFloatEqTest:testEqGasBothZero() (gas: 403) +LibDecimalFloatEqTest:testEqGasDifferentSigns() (gas: 457) +LibDecimalFloatEqTest:testEqGasExponentDiffOverflow() (gas: 552) +LibDecimalFloatEqTest:testEqMem((int256,int256),(int256,int256)) (runs: 5099, μ: 6486, ~: 6535) +LibDecimalFloatEqTest:testEqNotReverts(int256,int256,int256,int256) (runs: 5099, μ: 626, ~: 651) +LibDecimalFloatEqTest:testEqOneEAny(int256,int256) (runs: 5099, μ: 3435, ~: 3435) +LibDecimalFloatEqTest:testEqReference(int256,int256,int256,int256) (runs: 5099, μ: 9817, ~: 11305) +LibDecimalFloatEqTest:testEqX(int256) (runs: 5099, μ: 3430, ~: 3430) +LibDecimalFloatEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5098, μ: 4659, ~: 4657) +LibDecimalFloatEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5099, μ: 727, ~: 746) +LibDecimalFloatEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5098, μ: 3897, ~: 3922) +LibDecimalFloatEqTest:testEqXNotYExponents(int256,int256,int256,int256) (runs: 5099, μ: 4201, ~: 4279) +LibDecimalFloatEqTest:testEqZero(int256,int256) (runs: 5099, μ: 3412, ~: 3412) +LibDecimalFloatFloorTest:testFloorExamples() (gas: 27400) +LibDecimalFloatFloorTest:testFloorGas0() (gas: 463) +LibDecimalFloatFloorTest:testFloorGasTiny() (gas: 394) +LibDecimalFloatFloorTest:testFloorGasZero() (gas: 366) +LibDecimalFloatFloorTest:testFloorInRange(int256,int256) (runs: 5099, μ: 10080, ~: 10093) +LibDecimalFloatFloorTest:testFloorLessThanMin(int256,int256) (runs: 5099, μ: 9264, ~: 9440) +LibDecimalFloatFloorTest:testFloorMem((int256,int256)) (runs: 5099, μ: 6123, ~: 6101) +LibDecimalFloatFloorTest:testFloorNonNegative(int256,int256) (runs: 5099, μ: 8751, ~: 8528) +LibDecimalFloatFloorTest:testFloorNotReverts(int256,int256) (runs: 5099, μ: 483, ~: 472) +LibDecimalFloatFracTest:testFracExamples() (gas: 27404) +LibDecimalFloatFracTest:testFracGas0() (gas: 486) +LibDecimalFloatFracTest:testFracGasTiny() (gas: 372) +LibDecimalFloatFracTest:testFracGasZero() (gas: 377) +LibDecimalFloatFracTest:testFracInRange(int256,int256) (runs: 5099, μ: 9923, ~: 9935) +LibDecimalFloatFracTest:testFracLessThanMin(int256,int256) (runs: 5099, μ: 9244, ~: 9419) +LibDecimalFloatFracTest:testFracMem((int256,int256)) (runs: 5099, μ: 6069, ~: 6047) +LibDecimalFloatFracTest:testFracNonNegative(int256,int256) (runs: 5099, μ: 8728, ~: 8507) +LibDecimalFloatFracTest:testFracNotReverts(int256,int256) (runs: 5099, μ: 462, ~: 451) +LibDecimalFloatGtTest:testGtGasAZero() (gas: 404) +LibDecimalFloatGtTest:testGtGasBZero() (gas: 425) +LibDecimalFloatGtTest:testGtGasBothZero() (gas: 427) +LibDecimalFloatGtTest:testGtGasDifferentSigns() (gas: 405) +LibDecimalFloatGtTest:testGtGasExponentDiffOverflow() (gas: 507) +LibDecimalFloatGtTest:testGtMem((int256,int256),(int256,int256)) (runs: 5099, μ: 6430, ~: 6479) +LibDecimalFloatGtTest:testGtOneEAny(int256,int256) (runs: 5099, μ: 3439, ~: 3439) +LibDecimalFloatGtTest:testGtReference(int256,int256,int256,int256) (runs: 5099, μ: 9940, ~: 11563) +LibDecimalFloatGtTest:testGtX(int256) (runs: 5099, μ: 3411, ~: 3411) +LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int256,int256) (runs: 5099, μ: 9243, ~: 9014) +LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int256,int256) (runs: 5099, μ: 9706, ~: 9899) +LibDecimalFloatGtTest:testGtXNotY(int256,int256,int256,int256) (runs: 5099, μ: 4212, ~: 4289) +LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int256,int256,int256) (runs: 5099, μ: 11845, ~: 11803) +LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int256,int256) (runs: 5099, μ: 8970, ~: 8743) +LibDecimalFloatGtTest:testGtZero(int256,int256) (runs: 5099, μ: 3437, ~: 3437) LibDecimalFloatImplementationNormalizeTest:testExamples() (gas: 158985) -LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5096, μ: 3516, ~: 3522) -LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5096, μ: 9148, ~: 8984) +LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5099, μ: 3516, ~: 3522) +LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5099, μ: 9148, ~: 8984) LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentExamples() (gas: 12292) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5096, μ: 12560, ~: 12463) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5096, μ: 11365, ~: 11301) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5096, μ: 10778, ~: 10964) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5096, μ: 3562, ~: 3562) -LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5096, μ: 12976, ~: 12871) -LibDecimalFloatInvTest:testInvGas0() (gas: 726) -LibDecimalFloatInvTest:testInvReference(int256,int256) (runs: 5096, μ: 11731, ~: 11601) -LibDecimalFloatInvTest:testInvSlowGas0() (gas: 748) -LibDecimalFloatLog10Test:testExactLogs() (gas: 1225111) -LibDecimalFloatLog10Test:testExactLookups() (gas: 1241752) -LibDecimalFloatLog10Test:testInterpolatedLookups() (gas: 1219121) -LibDecimalFloatLog10Test:testSub1() (gas: 1216659) -LibDecimalFloatLtTest:testLtGasAZero() (gas: 445) -LibDecimalFloatLtTest:testLtGasBZero() (gas: 467) -LibDecimalFloatLtTest:testLtGasBothZero() (gas: 446) -LibDecimalFloatLtTest:testLtGasDifferentSigns() (gas: 468) -LibDecimalFloatLtTest:testLtGasExponentDiffOverflow() (gas: 529) -LibDecimalFloatLtTest:testLtNegativeVsPositive(int256,int256,int256,int256) (runs: 5096, μ: 11887, ~: 11844) -LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int256,int256) (runs: 5096, μ: 9475, ~: 9671) -LibDecimalFloatLtTest:testLtOneEAny(int256,int256) (runs: 5096, μ: 3459, ~: 3459) -LibDecimalFloatLtTest:testLtReference(int256,int256,int256,int256) (runs: 5096, μ: 9887, ~: 11440) -LibDecimalFloatLtTest:testLtVsEqualVsGt(int256,int256,int256,int256) (runs: 5096, μ: 4238, ~: 4310) -LibDecimalFloatLtTest:testLtX(int256) (runs: 5096, μ: 3430, ~: 3430) -LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int256,int256) (runs: 5096, μ: 9305, ~: 9076) -LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int256,int256) (runs: 5096, μ: 9746, ~: 9939) -LibDecimalFloatLtTest:testLtZero(int256,int256) (runs: 5096, μ: 3434, ~: 3434) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5097, μ: 12560, ~: 12463) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5099, μ: 11365, ~: 11301) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5099, μ: 10778, ~: 10966) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5099, μ: 3562, ~: 3562) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5098, μ: 12976, ~: 12871) +LibDecimalFloatInvTest:testInvGas0() (gas: 685) +LibDecimalFloatInvTest:testInvMem((int256,int256)) (runs: 5099, μ: 7279, ~: 7515) +LibDecimalFloatInvTest:testInvReference(int256,int256) (runs: 5098, μ: 11579, ~: 11449) +LibDecimalFloatInvTest:testInvSlowGas0() (gas: 666) +LibDecimalFloatLog10Test:testExactLogs() (gas: 1225056) +LibDecimalFloatLog10Test:testExactLookups() (gas: 1241554) +LibDecimalFloatLog10Test:testInterpolatedLookups() (gas: 1219044) +LibDecimalFloatLog10Test:testLog10Mem((int256,int256)) (runs: 5099, μ: 1831076, ~: 2415218) +LibDecimalFloatLog10Test:testSub1() (gas: 1216715) +LibDecimalFloatLtTest:testLtGasAZero() (gas: 447) +LibDecimalFloatLtTest:testLtGasBZero() (gas: 469) +LibDecimalFloatLtTest:testLtGasBothZero() (gas: 470) +LibDecimalFloatLtTest:testLtGasDifferentSigns() (gas: 403) +LibDecimalFloatLtTest:testLtGasExponentDiffOverflow() (gas: 509) +LibDecimalFloatLtTest:testLtMem((int256,int256),(int256,int256)) (runs: 5099, μ: 6411, ~: 6459) +LibDecimalFloatLtTest:testLtNegativeVsPositive(int256,int256,int256,int256) (runs: 5099, μ: 11911, ~: 11870) +LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int256,int256) (runs: 5099, μ: 9435, ~: 9631) +LibDecimalFloatLtTest:testLtOneEAny(int256,int256) (runs: 5099, μ: 3439, ~: 3439) +LibDecimalFloatLtTest:testLtReference(int256,int256,int256,int256) (runs: 5099, μ: 9846, ~: 11420) +LibDecimalFloatLtTest:testLtVsEqualVsGt(int256,int256,int256,int256) (runs: 5099, μ: 4174, ~: 4246) +LibDecimalFloatLtTest:testLtX(int256) (runs: 5099, μ: 3410, ~: 3410) +LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int256,int256) (runs: 5099, μ: 9265, ~: 9036) +LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int256,int256) (runs: 5099, μ: 9728, ~: 9921) +LibDecimalFloatLtTest:testLtZero(int256,int256) (runs: 5099, μ: 3414, ~: 3414) +LibDecimalFloatMaxTest:testMaxMem((int256,int256),(int256,int256)) (runs: 5099, μ: 7358, ~: 7405) +LibDecimalFloatMaxTest:testMaxX((int256,int256)) (runs: 5099, μ: 4395, ~: 4395) +LibDecimalFloatMaxTest:testMaxXY((int256,int256),(int256,int256)) (runs: 5099, μ: 5274, ~: 5344) +LibDecimalFloatMaxTest:testMaxXYEqual((int256,int256)) (runs: 5099, μ: 5420, ~: 5420) +LibDecimalFloatMaxTest:testMaxXYGreater((int256,int256),(int256,int256)) (runs: 5098, μ: 6466, ~: 6552) +LibDecimalFloatMaxTest:testMaxXYLess((int256,int256),(int256,int256)) (runs: 5096, μ: 6461, ~: 6575) +LibDecimalFloatMinTest:testMinMem((int256,int256),(int256,int256)) (runs: 5099, μ: 7377, ~: 7427) +LibDecimalFloatMinTest:testMinX((int256,int256)) (runs: 5099, μ: 4396, ~: 4396) +LibDecimalFloatMinTest:testMinXY((int256,int256),(int256,int256)) (runs: 5099, μ: 5294, ~: 5365) +LibDecimalFloatMinTest:testMinXYEqual((int256,int256)) (runs: 5099, μ: 5398, ~: 5398) +LibDecimalFloatMinTest:testMinXYGreater((int256,int256),(int256,int256)) (runs: 5097, μ: 6452, ~: 6554) +LibDecimalFloatMinTest:testMinXYLess((int256,int256),(int256,int256)) (runs: 5097, μ: 6468, ~: 6596) +LibDecimalFloatMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5099, μ: 12435, ~: 12470) +LibDecimalFloatMinusTest:testMinusMem((int256,int256)) (runs: 5099, μ: 5908, ~: 5908) LibDecimalFloatMixedTest:testDivide1Over3() (gas: 6557) -LibDecimalFloatMultiplyTest:testMultiply123456789987654321() (gas: 3712) -LibDecimalFloatMultiplyTest:testMultiply123456789987654321WithExponents(int128,int128) (runs: 5096, μ: 12502, ~: 12589) -LibDecimalFloatMultiplyTest:testMultiply1e181e19() (gas: 3716) -LibDecimalFloatMultiplyTest:testMultiplyGasOne() (gas: 379) +LibDecimalFloatMultiplyTest:testMultiply123456789987654321() (gas: 3708) +LibDecimalFloatMultiplyTest:testMultiply123456789987654321WithExponents(int128,int128) (runs: 5099, μ: 12545, ~: 12630) +LibDecimalFloatMultiplyTest:testMultiply1e181e19() (gas: 3690) +LibDecimalFloatMultiplyTest:testMultiplyGasOne() (gas: 375) LibDecimalFloatMultiplyTest:testMultiplyGasZero() (gas: 342) -LibDecimalFloatMultiplyTest:testMultiplyNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5096, μ: 12879, ~: 12291) -LibDecimalFloatMultiplyTest:testMultiplyOneOne() (gas: 3689) +LibDecimalFloatMultiplyTest:testMultiplyMem((int256,int256),(int256,int256)) (runs: 5099, μ: 7567, ~: 7050) +LibDecimalFloatMultiplyTest:testMultiplyNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5099, μ: 12861, ~: 12309) +LibDecimalFloatMultiplyTest:testMultiplyOneOne() (gas: 3707) LibDecimalFloatMultiplyTest:testMultiplyOneZero() (gas: 3653) LibDecimalFloatMultiplyTest:testMultiplyZero0Exponent() (gas: 3609) -LibDecimalFloatMultiplyTest:testMultiplyZeroAnyExponent(int64,int64) (runs: 5096, μ: 3896, ~: 3896) -LibDecimalFloatMultiplyTest:testMultiplyZeroOne() (gas: 3610) -LibDecimalFloatPackTest:testNormalizedRoundTrip(int256,int256) (runs: 5096, μ: 10216, ~: 10053) -LibDecimalFloatPackTest:testPartsRoundTrip(int128,int128) (runs: 5096, μ: 4493, ~: 4493) -LibDecimalFloatPower10Test:testExactLookups() (gas: 1253736) -LibDecimalFloatPower10Test:testExactPowers() (gas: 1228102) -LibDecimalFloatPower10Test:testInterpolatedLookupsPower() (gas: 1229822) -LibDecimalFloatPower10Test:testNoRevert(int256,int256) (runs: 5096, μ: 1218021, ~: 1218943) -LibDecimalFloatPowerTest:testPowers() (gas: 1223912) -LibDecimalFloatPowerTest:testRoundTrip() (gas: 1348368) -LibDecimalFloatSubTest:testMinusIsSubZero(int256,int256,int256) (runs: 5096, μ: 12441, ~: 12478) -LibDecimalFloatSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5096, μ: 15474, ~: 15376) -LibDecimalFloatSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5096, μ: 15715, ~: 15619) +LibDecimalFloatMultiplyTest:testMultiplyZeroAnyExponent(int64,int64) (runs: 5099, μ: 3896, ~: 3896) +LibDecimalFloatMultiplyTest:testMultiplyZeroOne() (gas: 3654) +LibDecimalFloatPackTest:testNormalizedRoundTrip(int256,int256) (runs: 5099, μ: 10161, ~: 10000) +LibDecimalFloatPackTest:testPackMem((int256,int256)) (runs: 5099, μ: 4941, ~: 4774) +LibDecimalFloatPackTest:testPartsRoundTrip(int128,int128) (runs: 5099, μ: 4493, ~: 4493) +LibDecimalFloatPackTest:testUnpackMem(bytes32) (runs: 5099, μ: 5899, ~: 5899) +LibDecimalFloatPower10Test:testExactLookups() (gas: 1253748) +LibDecimalFloatPower10Test:testExactPowers() (gas: 1228108) +LibDecimalFloatPower10Test:testInterpolatedLookupsPower() (gas: 1229825) +LibDecimalFloatPower10Test:testNoRevert(int256,int256) (runs: 5099, μ: 1218020, ~: 1218995) +LibDecimalFloatPower10Test:testPower10Mem((int256,int256)) (runs: 5099, μ: 2017717, ~: 2416856) +LibDecimalFloatPowerTest:testPowerMem((int256,int256),(int256,int256)) (runs: 5099, μ: 2346830, ~: 2417050) +LibDecimalFloatPowerTest:testPowers() (gas: 1223498) +LibDecimalFloatPowerTest:testRoundTrip() (gas: 1343164) +LibDecimalFloatSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5099, μ: 15312, ~: 15201) +LibDecimalFloatSubTest:testSubMem((int256,int256),(int256,int256)) (runs: 5099, μ: 8998, ~: 9242) +LibDecimalFloatSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5099, μ: 15556, ~: 15464) LibLogTableBytesTest:testToBytesAntiLogTableDec() (gas: 153225) LibLogTableBytesTest:testToBytesAntiLogTableDecSmall() (gas: 158036) LibLogTableBytesTest:testToBytesLogTableDec() (gas: 137284) @@ -166,7 +199,7 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatEDot() (gas: 4159) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert5() (gas: 4145) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert6() (gas: 4092) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponents() (gas: 393083) -LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5096, μ: 45455, ~: 36805) +LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5099, μ: 45464, ~: 36819) LibParseDecimalFloatTest:testParseLiteralDecimalFloatLeadingZeros() (gas: 59042) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeE() (gas: 6025) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeFrac() (gas: 5095) diff --git a/src/lib/LibDecimalFloat.sol b/src/lib/LibDecimalFloat.sol index d198234b..0f4ff635 100644 --- a/src/lib/LibDecimalFloat.sol +++ b/src/lib/LibDecimalFloat.sol @@ -1108,4 +1108,72 @@ library LibDecimalFloat { (result.signedCoefficient, result.exponent) = power(tablesDataContract, a.signedCoefficient, a.exponent, b.signedCoefficient, b.exponent); } + + /// Returns the minimum of two values. + /// Convenience for `a < b ? a : b`. + /// @param signedCoefficientA The signed coefficient of the first floating + /// point number. + /// @param exponentA The exponent of the first floating point number. + /// @param signedCoefficientB The signed coefficient of the second floating + /// point number. + /// @param exponentB The exponent of the second floating point number. + /// @return signedCoefficient The signed coefficient of the minimum value. + /// @return exponent The exponent of the minimum value. + function min(int256 signedCoefficientA, int256 exponentA, int256 signedCoefficientB, int256 exponentB) + internal + pure + returns (int256, int256) + { + if (lt(signedCoefficientA, exponentA, signedCoefficientB, exponentB)) { + return (signedCoefficientA, exponentA); + } else { + return (signedCoefficientB, exponentB); + } + } + + /// Same as min, but accepts a Float struct instead of separate values. + /// Costs more gas but helps mitigate stack depth issues, and is more + /// ergonomic for the caller. + /// @param a The Float struct containing the signed coefficient and + /// exponent of the first floating point number. + /// @param b The Float struct containing the signed coefficient and + /// exponent of the second floating point number. + function min(Float memory a, Float memory b) internal pure returns (Float memory result) { + (result.signedCoefficient, result.exponent) = + min(a.signedCoefficient, a.exponent, b.signedCoefficient, b.exponent); + } + + /// Returns the maximum of two values. + /// Convenience for `a > b ? a : b`. + /// @param signedCoefficientA The signed coefficient of the first floating + /// point number. + /// @param exponentA The exponent of the first floating point number. + /// @param signedCoefficientB The signed coefficient of the second floating + /// point number. + /// @param exponentB The exponent of the second floating point number. + /// @return signedCoefficient The signed coefficient of the maximum value. + /// @return exponent The exponent of the maximum value. + function max(int256 signedCoefficientA, int256 exponentA, int256 signedCoefficientB, int256 exponentB) + internal + pure + returns (int256, int256) + { + if (gt(signedCoefficientA, exponentA, signedCoefficientB, exponentB)) { + return (signedCoefficientA, exponentA); + } else { + return (signedCoefficientB, exponentB); + } + } + + /// Same as max, but accepts a Float struct instead of separate values. + /// Costs more gas but helps mitigate stack depth issues, and is more + /// ergonomic for the caller. + /// @param a The Float struct containing the signed coefficient and + /// exponent of the first floating point number. + /// @param b The Float struct containing the signed coefficient and + /// exponent of the second floating point number. + function max(Float memory a, Float memory b) internal pure returns (Float memory result) { + (result.signedCoefficient, result.exponent) = + max(a.signedCoefficient, a.exponent, b.signedCoefficient, b.exponent); + } } diff --git a/test/src/lib/LibDecimalFloat.max.t.sol b/test/src/lib/LibDecimalFloat.max.t.sol new file mode 100644 index 00000000..d46bbc26 --- /dev/null +++ b/test/src/lib/LibDecimalFloat.max.t.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +import {Test} from "forge-std/Test.sol"; +import {LibDecimalFloat, Float} from "src/lib/LibDecimalFloat.sol"; + +contract LibDecimalFloatMaxTest is Test { + using LibDecimalFloat for Float; + + function maxExternal(int256 signedCoefficientA, int256 exponentA, int256 signedCoefficientB, int256 exponentB) + external + pure + returns (int256, int256) + { + return LibDecimalFloat.max(signedCoefficientA, exponentA, signedCoefficientB, exponentB); + } + + function maxExternal(Float memory floatA, Float memory floatB) external pure returns (Float memory) { + return floatA.max(floatB); + } + /// Test to verify that stack-based and memory-based implementations produce the same results. + + function testMaxMem(Float memory a, Float memory b) external { + try this.maxExternal(a.signedCoefficient, a.exponent, b.signedCoefficient, b.exponent) returns ( + int256 signedCoefficient, int256 exponent + ) { + Float memory actual = this.maxExternal(a, b); + assertEq(signedCoefficient, actual.signedCoefficient); + assertEq(exponent, actual.exponent); + } catch (bytes memory err) { + vm.expectRevert(err); + this.maxExternal(a, b); + } + } + /// x.max(x) + + function testMaxX(Float memory x) external pure { + Float memory y = x.max(x); + assertTrue(y.eq(x), "x.max(x) != x"); + } + /// x.max(y) == y.max(x) + + function testMaxXY(Float memory x, Float memory y) external pure { + Float memory maxXY = x.max(y); + Float memory maxYX = y.max(x); + assertTrue(maxXY.eq(maxYX), "maxXY != maxYX"); + } + /// x.max(y) for x == y + + function testMaxXYEqual(Float memory x) external pure { + Float memory y = Float(x.signedCoefficient, x.exponent); + Float memory z = x.max(y); + assertTrue(z.eq(x), "x.max(y) != x"); + assertTrue(z.eq(y), "x.max(y) != y"); + } + /// x.max(y) for x > y + + function testMaxXYGreater(Float memory x, Float memory y) external pure { + vm.assume(x.gt(y)); + Float memory z = x.max(y); + assertTrue(z.eq(x), "x.max(y) == x"); + assertTrue(!z.eq(y), "x.max(y) != y"); + } + /// x.max(y) for x < y + + function testMaxXYLess(Float memory x, Float memory y) external pure { + vm.assume(x.lt(y)); + Float memory z = x.max(y); + assertTrue(!z.eq(x), "x.max(y) != x"); + assertTrue(z.eq(y), "x.max(y) == y"); + } +} diff --git a/test/src/lib/LibDecimalFloat.min.t.sol b/test/src/lib/LibDecimalFloat.min.t.sol new file mode 100644 index 00000000..cc1af8dd --- /dev/null +++ b/test/src/lib/LibDecimalFloat.min.t.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +import {Test} from "forge-std/Test.sol"; +import {LibDecimalFloat, Float} from "src/lib/LibDecimalFloat.sol"; + +contract LibDecimalFloatMinTest is Test { + using LibDecimalFloat for Float; + + function minExternal(int256 signedCoefficientA, int256 exponentA, int256 signedCoefficientB, int256 exponentB) + external + pure + returns (int256, int256) + { + return LibDecimalFloat.min(signedCoefficientA, exponentA, signedCoefficientB, exponentB); + } + + function minExternal(Float memory floatA, Float memory floatB) external pure returns (Float memory) { + return floatA.min(floatB); + } + + /// Test to verify that stack-based and memory-based implementations produce the same results. + function testMinMem(Float memory a, Float memory b) external { + try this.minExternal(a.signedCoefficient, a.exponent, b.signedCoefficient, b.exponent) returns ( + int256 signedCoefficient, int256 exponent + ) { + Float memory actual = this.minExternal(a, b); + assertEq(signedCoefficient, actual.signedCoefficient); + assertEq(exponent, actual.exponent); + } catch (bytes memory err) { + vm.expectRevert(err); + this.minExternal(a, b); + } + } + + /// x.min(x) + function testMinX(Float memory x) external pure { + Float memory y = x.min(x); + assertTrue(y.eq(x), "x.min(x) != x"); + } + + /// x.min(y) == y.min(x) + function testMinXY(Float memory x, Float memory y) external pure { + Float memory minXY = x.min(y); + Float memory minYX = y.min(x); + assertTrue(minXY.eq(minYX), "minXY != minYX"); + } + + /// x.min(y) for x == y + function testMinXYEqual(Float memory x) external pure { + Float memory y = Float(x.signedCoefficient, x.exponent); + Float memory z = x.min(y); + assertTrue(z.eq(x), "x.min(y) != x"); + assertTrue(z.eq(y), "x.min(y) != y"); + } + + /// x.min(y) for x < y + function testMinXYLess(Float memory x, Float memory y) external pure { + vm.assume(x.lt(y)); + Float memory z = x.min(y); + assertTrue(z.eq(x), "x.min(y) != x"); + assertTrue(!z.eq(y), "x.min(y) == y"); + } + + /// x.min(y) for x > y + function testMinXYGreater(Float memory x, Float memory y) external pure { + vm.assume(x.gt(y)); + Float memory z = x.min(y); + assertTrue(z.eq(y), "x.min(y) != y"); + assertTrue(!z.eq(x), "x.min(y) == x"); + } +}