diff --git a/.gas-snapshot b/.gas-snapshot index 8f05dfc3..461ebb55 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,185 +1,186 @@ -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) +LibDecimalFloatAbsTest:testAbsMem((int256,int256)) (runs: 5101, μ: 5951, ~: 5890) +LibDecimalFloatAbsTest:testAbsMinValue(int256) (runs: 5101, μ: 4405, ~: 4405) +LibDecimalFloatAbsTest:testAbsNegative(int256,int256) (runs: 5101, μ: 9370, ~: 9569) +LibDecimalFloatAbsTest:testAbsNonNegative(int256,int256) (runs: 5101, μ: 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:testAddMem((int256,int256),(int256,int256)) (runs: 5101, μ: 7765, ~: 8009) +LibDecimalFloatDecimalAddTest:testAddNeverRevert(int256,int256,int256,int256) (runs: 5101, μ: 12353, ~: 12322) LibDecimalFloatDecimalAddTest:testAddOneOneNotNormalized() (gas: 5349) LibDecimalFloatDecimalAddTest:testAddOneOnePreNormalized() (gas: 4228) LibDecimalFloatDecimalAddTest:testAddOneZero() (gas: 3634) -LibDecimalFloatDecimalAddTest:testAddSameExponentSameCoefficient(int256,int256) (runs: 5099, μ: 5700, ~: 5746) +LibDecimalFloatDecimalAddTest:testAddSameExponentSameCoefficient(int256,int256) (runs: 5101, μ: 5702, ~: 5746) LibDecimalFloatDecimalAddTest:testAddZero() (gas: 3632) -LibDecimalFloatDecimalAddTest:testAddZeroAnyExponent(int128) (runs: 5099, μ: 8902, ~: 8892) +LibDecimalFloatDecimalAddTest:testAddZeroAnyExponent(int128) (runs: 5101, μ: 8879, ~: 8914) LibDecimalFloatDecimalAddTest:testAddZeroOne() (gas: 3633) -LibDecimalFloatDecimalAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5099, μ: 13500, ~: 13410) +LibDecimalFloatDecimalAddTest:testAddZeroToAnyNonZero(int256,int256,int256) (runs: 5101, μ: 13178, ~: 13156) LibDecimalFloatDecimalAddTest:testAddingSmallToLargeReturnsLargeExamples() (gas: 19216) -LibDecimalFloatDecimalAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5098, μ: 16598, ~: 16454) +LibDecimalFloatDecimalAddTest:testAddingSmallToLargeReturnsLargeFuzz(int256,int256,int256,int256) (runs: 5098, μ: 16280, ~: 16250) 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:testFromFixedDecimalLosslessFail(uint256,uint8) (runs: 5100, μ: 9232, ~: 9281) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessMem(uint256,uint8) (runs: 5101, μ: 4416, ~: 4423) +LibDecimalFloatDecimalLosslessTest:testFromFixedDecimalLosslessPass(uint256,uint8) (runs: 5101, μ: 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) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessMem((int256,int256),uint8) (runs: 5101, μ: 6854, ~: 7838) +LibDecimalFloatDecimalLosslessTest:testToFixedDecimalLosslessPass(int256,int256,uint8) (runs: 5101, μ: 14674, ~: 14633) +LibDecimalFloatDecimalTest:testFixedDecimalRoundTripLossless(uint256,uint8) (runs: 5101, μ: 8843, ~: 8620) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyComplicated() (gas: 600575) -LibDecimalFloatDecimalTest:testFromFixedDecimalLossyMem(uint256,uint8) (runs: 5099, μ: 5321, ~: 5318) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyMem(uint256,uint8) (runs: 5101, μ: 5321, ~: 5318) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMax() (gas: 588036) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyNormalizedMaxPlusOne() (gas: 618935) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOne() (gas: 600509) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOneMillion() (gas: 600532) LibDecimalFloatDecimalTest:testFromFixedDecimalLossyOverflow() (gas: 629579) -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:testFromFixedDecimalLossyTruncateOne(uint256,uint8) (runs: 5101, μ: 5589, ~: 5547) +LibDecimalFloatDecimalTest:testFromFixedDecimalLossyTruncateZero(uint256,uint8) (runs: 5101, μ: 7033, ~: 5559) +LibDecimalFloatDecimalTest:testToFixedDecimalLosslessScaleUp(int256,int256,uint8) (runs: 5098, μ: 14946, ~: 14885) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyExponentOverflow(int256,int256,uint8) (runs: 5101, μ: 13526, ~: 13300) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyIdentity(int256,uint8) (runs: 5101, μ: 9466, ~: 9236) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyMem((int256,int256),uint8) (runs: 5101, μ: 6917, ~: 7893) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyNegative(int256,int256,uint8) (runs: 5101, μ: 9077, ~: 9278) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyScaleUpOverflow(int256,int256,uint8) (runs: 5099, μ: 12891, ~: 13099) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncate(int256,int256,uint8) (runs: 5101, μ: 13472, ~: 13252) LibDecimalFloatDecimalTest:testToFixedDecimalLossyTruncateLossless() (gas: 13162) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5099, μ: 12420, ~: 12355) -LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5099, μ: 4368, ~: 4368) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyUnderflow(int256,int256,uint8) (runs: 5101, μ: 12420, ~: 12355) +LibDecimalFloatDecimalTest:testToFixedDecimalLossyZero(int256,uint8) (runs: 5101, μ: 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:testDivideMem((int256,int256),(int256,int256)) (runs: 5101, μ: 9157, ~: 9320) LibDecimalFloatDivideTest:testDivideNegative1Over3() (gas: 5722) LibDecimalFloatDivideTest:testDivideOOMs5and2() (gas: 4519) LibDecimalFloatDivideTest:testDivideOOMsOverTen() (gas: 5323) LibDecimalFloatDivideTest:testDivideTenOverOOMs() (gas: 5316) -LibDecimalFloatDivideTest:testUnnormalizedThreesDivision0(int256,int256) (runs: 103, μ: 19158189, ~: 19158411) +LibDecimalFloatDivideTest:testUnnormalizedThreesDivision0(int256,int256) (runs: 105, μ: 19158378, ~: 19158310) 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) +LibDecimalFloatEqTest:testEqMem((int256,int256),(int256,int256)) (runs: 5101, μ: 6486, ~: 6535) +LibDecimalFloatEqTest:testEqNotReverts(int256,int256,int256,int256) (runs: 5101, μ: 626, ~: 651) +LibDecimalFloatEqTest:testEqOneEAny(int256,int256) (runs: 5101, μ: 3435, ~: 3435) +LibDecimalFloatEqTest:testEqReference(int256,int256,int256,int256) (runs: 5101, μ: 9815, ~: 11305) +LibDecimalFloatEqTest:testEqX(int256) (runs: 5101, μ: 3430, ~: 3430) +LibDecimalFloatEqTest:testEqXEAnyVsXEAny(int256,int256,int256) (runs: 5100, μ: 4659, ~: 4657) +LibDecimalFloatEqTest:testEqXEqY(int256,int256,int256,int256) (runs: 5101, μ: 727, ~: 746) +LibDecimalFloatEqTest:testEqXNotY(int256,int256,int256,int256) (runs: 5100, μ: 3897, ~: 3922) +LibDecimalFloatEqTest:testEqXNotYExponents(int256,int256,int256,int256) (runs: 5101, μ: 4201, ~: 4279) +LibDecimalFloatEqTest:testEqZero(int256,int256) (runs: 5101, μ: 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) +LibDecimalFloatFloorTest:testFloorInRange(int256,int256) (runs: 5101, μ: 10080, ~: 10093) +LibDecimalFloatFloorTest:testFloorLessThanMin(int256,int256) (runs: 5101, μ: 9263, ~: 9440) +LibDecimalFloatFloorTest:testFloorMem((int256,int256)) (runs: 5101, μ: 6123, ~: 6101) +LibDecimalFloatFloorTest:testFloorNonNegative(int256,int256) (runs: 5101, μ: 8751, ~: 8528) +LibDecimalFloatFloorTest:testFloorNotReverts(int256,int256) (runs: 5101, μ: 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) +LibDecimalFloatFracTest:testFracInRange(int256,int256) (runs: 5101, μ: 9923, ~: 9935) +LibDecimalFloatFracTest:testFracLessThanMin(int256,int256) (runs: 5101, μ: 9243, ~: 9419) +LibDecimalFloatFracTest:testFracMem((int256,int256)) (runs: 5101, μ: 6069, ~: 6047) +LibDecimalFloatFracTest:testFracNonNegative(int256,int256) (runs: 5101, μ: 8728, ~: 8507) +LibDecimalFloatFracTest:testFracNotReverts(int256,int256) (runs: 5101, μ: 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) +LibDecimalFloatGtTest:testGtMem((int256,int256),(int256,int256)) (runs: 5101, μ: 6430, ~: 6479) +LibDecimalFloatGtTest:testGtOneEAny(int256,int256) (runs: 5101, μ: 3439, ~: 3439) +LibDecimalFloatGtTest:testGtReference(int256,int256,int256,int256) (runs: 5101, μ: 9938, ~: 11563) +LibDecimalFloatGtTest:testGtX(int256) (runs: 5101, μ: 3411, ~: 3411) +LibDecimalFloatGtTest:testGtXEAnyVsXEAny(int256,int256,int256) (runs: 5101, μ: 9243, ~: 9014) +LibDecimalFloatGtTest:testGtXEAnyVsXEAnyNegative(int256,int256,int256) (runs: 5101, μ: 9706, ~: 9899) +LibDecimalFloatGtTest:testGtXNotY(int256,int256,int256,int256) (runs: 5101, μ: 4212, ~: 4289) +LibDecimalFloatGtTest:testGtXPositiveYNegative(int256,int256,int256,int256) (runs: 5101, μ: 11846, ~: 11803) +LibDecimalFloatGtTest:testGtXPositiveYZero(int256,int256,int256) (runs: 5101, μ: 8970, ~: 8743) +LibDecimalFloatGtTest:testGtZero(int256,int256) (runs: 5101, μ: 3437, ~: 3437) LibDecimalFloatImplementationNormalizeTest:testExamples() (gas: 158985) -LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5099, μ: 3516, ~: 3522) -LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5099, μ: 9148, ~: 8984) +LibDecimalFloatImplementationNormalizeTest:testIsNormalizedReference(int256,int256) (runs: 5101, μ: 3516, ~: 3522) +LibDecimalFloatImplementationNormalizeTest:testNormalized(int256,int256) (runs: 5101, μ: 8977, ~: 8940) LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentExamples() (gas: 12292) -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) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentOverflowRescaleRevert(int256,int256,int256) (runs: 5098, μ: 12560, ~: 12463) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerExponentVeryLargeDiffRevert(int256,int256,int256) (runs: 5101, μ: 11365, ~: 11301) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentLargerTargetExponentNoRevert(int256,int256,int256) (runs: 5101, μ: 10778, ~: 10962) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSameExponentNoop(int256,int256) (runs: 5101, μ: 3562, ~: 3562) +LibDecimalFloatImplementationWithTargetExponentTest:testWithTargetExponentSmallerExponentNoRevert(int256,int256,int256) (runs: 5099, μ: 12976, ~: 12871) LibDecimalFloatInvTest:testInvGas0() (gas: 685) -LibDecimalFloatInvTest:testInvMem((int256,int256)) (runs: 5099, μ: 7279, ~: 7515) -LibDecimalFloatInvTest:testInvReference(int256,int256) (runs: 5098, μ: 11579, ~: 11449) +LibDecimalFloatInvTest:testInvMem((int256,int256)) (runs: 5101, μ: 7539, ~: 7657) +LibDecimalFloatInvTest:testInvReference(int256,int256) (runs: 5100, μ: 11419, ~: 11394) 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:testLog10Mem((int256,int256)) (runs: 5101, μ: 1628855, ~: 1223860) 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) +LibDecimalFloatLtTest:testLtMem((int256,int256),(int256,int256)) (runs: 5101, μ: 6411, ~: 6459) +LibDecimalFloatLtTest:testLtNegativeVsPositive(int256,int256,int256,int256) (runs: 5101, μ: 11911, ~: 11870) +LibDecimalFloatLtTest:testLtNegativeVsZero(int256,int256,int256) (runs: 5101, μ: 9435, ~: 9631) +LibDecimalFloatLtTest:testLtOneEAny(int256,int256) (runs: 5101, μ: 3439, ~: 3439) +LibDecimalFloatLtTest:testLtReference(int256,int256,int256,int256) (runs: 5101, μ: 9844, ~: 11420) +LibDecimalFloatLtTest:testLtVsEqualVsGt(int256,int256,int256,int256) (runs: 5101, μ: 4174, ~: 4246) +LibDecimalFloatLtTest:testLtX(int256) (runs: 5101, μ: 3410, ~: 3410) +LibDecimalFloatLtTest:testLtXEAnyVsXEAny(int256,int256,int256) (runs: 5101, μ: 9265, ~: 9036) +LibDecimalFloatLtTest:testLtXEAnyVsXEAnyNegative(int256,int256,int256) (runs: 5101, μ: 9728, ~: 9921) +LibDecimalFloatLtTest:testLtZero(int256,int256) (runs: 5101, μ: 3414, ~: 3414) +LibDecimalFloatMaxTest:testMaxMem((int256,int256),(int256,int256)) (runs: 5101, μ: 7358, ~: 7405) +LibDecimalFloatMaxTest:testMaxX((int256,int256)) (runs: 5101, μ: 4395, ~: 4395) +LibDecimalFloatMaxTest:testMaxXY((int256,int256),(int256,int256)) (runs: 5101, μ: 5274, ~: 5344) +LibDecimalFloatMaxTest:testMaxXYEqual((int256,int256)) (runs: 5101, μ: 5420, ~: 5420) +LibDecimalFloatMaxTest:testMaxXYGreater((int256,int256),(int256,int256)) (runs: 5097, μ: 6466, ~: 6552) +LibDecimalFloatMaxTest:testMaxXYLess((int256,int256),(int256,int256)) (runs: 5099, μ: 6461, ~: 6575) +LibDecimalFloatMinTest:testMinMem((int256,int256),(int256,int256)) (runs: 5101, μ: 7377, ~: 7427) +LibDecimalFloatMinTest:testMinX((int256,int256)) (runs: 5101, μ: 4396, ~: 4396) +LibDecimalFloatMinTest:testMinXY((int256,int256),(int256,int256)) (runs: 5101, μ: 5294, ~: 5365) +LibDecimalFloatMinTest:testMinXYEqual((int256,int256)) (runs: 5101, μ: 5398, ~: 5398) +LibDecimalFloatMinTest:testMinXYGreater((int256,int256),(int256,int256)) (runs: 5096, μ: 6452, ~: 6554) +LibDecimalFloatMinTest:testMinXYLess((int256,int256),(int256,int256)) (runs: 5100, μ: 6468, ~: 6596) +LibDecimalFloatMinusTest:testMinusIsSubZero(int256,int256,int256) (runs: 5101, μ: 12110, ~: 12079) +LibDecimalFloatMinusTest:testMinusMem((int256,int256)) (runs: 5101, μ: 5908, ~: 5908) LibDecimalFloatMixedTest:testDivide1Over3() (gas: 6557) LibDecimalFloatMultiplyTest:testMultiply123456789987654321() (gas: 3708) -LibDecimalFloatMultiplyTest:testMultiply123456789987654321WithExponents(int128,int128) (runs: 5099, μ: 12545, ~: 12630) +LibDecimalFloatMultiplyTest:testMultiply123456789987654321WithExponents(int128,int128) (runs: 5101, μ: 12544, ~: 12630) LibDecimalFloatMultiplyTest:testMultiply1e181e19() (gas: 3690) LibDecimalFloatMultiplyTest:testMultiplyGasOne() (gas: 375) LibDecimalFloatMultiplyTest:testMultiplyGasZero() (gas: 342) -LibDecimalFloatMultiplyTest:testMultiplyMem((int256,int256),(int256,int256)) (runs: 5099, μ: 7567, ~: 7050) -LibDecimalFloatMultiplyTest:testMultiplyNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5099, μ: 12861, ~: 12309) +LibDecimalFloatMultiplyTest:testMultiplyMem((int256,int256),(int256,int256)) (runs: 5101, μ: 7853, ~: 7050) +LibDecimalFloatMultiplyTest:testMultiplyNotRevertAnyExpectation(int256,int256,int256,int256) (runs: 5101, μ: 12524, ~: 11740) LibDecimalFloatMultiplyTest:testMultiplyOneOne() (gas: 3707) LibDecimalFloatMultiplyTest:testMultiplyOneZero() (gas: 3653) LibDecimalFloatMultiplyTest:testMultiplyZero0Exponent() (gas: 3609) -LibDecimalFloatMultiplyTest:testMultiplyZeroAnyExponent(int64,int64) (runs: 5099, μ: 3896, ~: 3896) +LibDecimalFloatMultiplyTest:testMultiplyZeroAnyExponent(int64,int64) (runs: 5101, μ: 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) +LibDecimalFloatNormalizeTest:testNormalizeMem((int256,int256)) (runs: 5101, μ: 6893, ~: 6974) +LibDecimalFloatPackTest:testNormalizedRoundTrip(int256,int32) (runs: 5100, μ: 4885, ~: 4921) +LibDecimalFloatPackTest:testPackMem((int256,int256)) (runs: 5101, μ: 4889, ~: 4721) +LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5101, μ: 4505, ~: 4506) +LibDecimalFloatPackTest:testUnpackMem(bytes32) (runs: 5101, μ: 5941, ~: 5941) +LibDecimalFloatPower10Test:testExactLookups() (gas: 1241679) +LibDecimalFloatPower10Test:testExactPowers() (gas: 1221631) +LibDecimalFloatPower10Test:testInterpolatedLookupsPower() (gas: 1225739) +LibDecimalFloatPower10Test:testNoRevert(int256,int256) (runs: 5100, μ: 1217988, ~: 1218995) +LibDecimalFloatPower10Test:testPower10Mem((int256,int256)) (runs: 5101, μ: 2006090, ~: 2416856) +LibDecimalFloatPowerTest:testPowerMem((int256,int256),(int256,int256)) (runs: 5101, μ: 2294617, ~: 2422994) 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) -LibFormatDecimalFloatTest:testFormatMem((int256,int256)) (runs: 5099, μ: 6030, ~: 6688) -LibFormatDecimalFloatTest:testRoundTrip(uint256) (runs: 5099, μ: 23970, ~: 18699) +LibDecimalFloatSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5101, μ: 14997, ~: 15007) +LibDecimalFloatSubTest:testSubMem((int256,int256),(int256,int256)) (runs: 5101, μ: 9557, ~: 9782) +LibDecimalFloatSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5101, μ: 15219, ~: 15171) +LibFormatDecimalFloatTest:testFormatMem((int256,int256)) (runs: 5101, μ: 6029, ~: 6688) +LibFormatDecimalFloatTest:testRoundTrip(uint256) (runs: 5101, μ: 23976, ~: 18699) LibLogTableBytesTest:testToBytesAntiLogTableDec() (gas: 153225) LibLogTableBytesTest:testToBytesAntiLogTableDecSmall() (gas: 158036) LibLogTableBytesTest:testToBytesLogTableDec() (gas: 137284) @@ -201,7 +202,7 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatEDot() (gas: 4159) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert5() (gas: 4145) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponentRevert6() (gas: 4092) LibParseDecimalFloatTest:testParseLiteralDecimalFloatExponents() (gas: 393083) -LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5099, μ: 45507, ~: 36636) +LibParseDecimalFloatTest:testParseLiteralDecimalFloatFuzz(uint256,uint8,bool) (runs: 5101, μ: 45503, ~: 36636) LibParseDecimalFloatTest:testParseLiteralDecimalFloatLeadingZeros() (gas: 59042) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeE() (gas: 6048) LibParseDecimalFloatTest:testParseLiteralDecimalFloatNegativeFrac() (gas: 5095) @@ -209,4 +210,4 @@ LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert0() (gas: 27 LibParseDecimalFloatTest:testParseLiteralDecimalFloatPrecisionRevert1() (gas: 27353) LibParseDecimalFloatTest:testParseLiteralDecimalFloatSpecific() (gas: 22682) LibParseDecimalFloatTest:testParseLiteralDecimalFloatUnrelated() (gas: 31978) -LibParseDecimalFloatTest:testParseMem(string) (runs: 5099, μ: 9205, ~: 9168) \ No newline at end of file +LibParseDecimalFloatTest:testParseMem(string) (runs: 5101, μ: 9205, ~: 9168) \ No newline at end of file diff --git a/src/lib/LibDecimalFloat.sol b/src/lib/LibDecimalFloat.sol index 24558393..0143a318 100644 --- a/src/lib/LibDecimalFloat.sol +++ b/src/lib/LibDecimalFloat.sol @@ -20,12 +20,12 @@ import { LibDecimalFloatImplementation, NORMALIZED_ZERO_SIGNED_COEFFICIENT, NORMALIZED_ZERO_EXPONENT, - EXPONENT_MIN, - EXPONENT_MAX, NORMALIZED_MIN, NORMALIZED_MAX, EXPONENT_STEP_SIZE, - SIGNED_NORMALIZED_MAX + SIGNED_NORMALIZED_MAX, + EXPONENT_MAX, + EXPONENT_MIN } from "./implementation/LibDecimalFloatImplementation.sol"; type PackedFloat is bytes32; @@ -51,8 +51,8 @@ struct Float { /// @title LibDecimalFloat /// Floating point math library for Rainlang. -/// Broadly implements decimal floating point math with 128 signed bits for the -/// coefficient and 128 signed bits for the exponent. Notably the implementation +/// Broadly implements decimal floating point math with 224 signed bits for the +/// coefficient and 32 signed bits for the exponent. Notably the implementation /// differs from standard specifications in a few key areas: /// /// - There is no concept of NaN or Infinity. @@ -283,8 +283,9 @@ library LibDecimalFloat { return toFixedDecimalLossless(float.signedCoefficient, float.exponent, decimals); } - /// Pack a signed coefficient and exponent into a single uint256. Clearly - /// this involves fitting 64 bytes into 32 bytes, so there will be data loss. + /// 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 @@ -298,12 +299,31 @@ library LibDecimalFloat { /// @return packed The packed representation of the signed coefficient and /// exponent. function pack(int256 signedCoefficient, int256 exponent) internal pure returns (PackedFloat packed) { - if (int128(signedCoefficient) != signedCoefficient || int128(exponent) != exponent) { - (signedCoefficient, exponent) = LibDecimalFloatImplementation.normalize(signedCoefficient, exponent); + if (signedCoefficient == 0) { + return PackedFloat.wrap(0); + } + + if (int224(signedCoefficient) != signedCoefficient) { + if (signedCoefficient / 1e72 != 0) { + signedCoefficient /= 1e5; + exponent += 5; + } + + while (int224(signedCoefficient) != signedCoefficient) { + signedCoefficient /= 10; + ++exponent; + } } - uint256 mask = type(uint128).max; + + if (int32(exponent) != exponent) { + revert ExponentOverflow(signedCoefficient, exponent); + } + + // Need a mask to zero out the bits that could be set to 1 if the + // coefficient is negative. + uint256 mask = type(uint224).max; assembly ("memory-safe") { - packed := or(and(signedCoefficient, mask), shl(0x80, exponent)) + packed := or(and(signedCoefficient, mask), shl(0xe0, exponent)) } } @@ -320,10 +340,10 @@ library LibDecimalFloat { /// representation. /// @return exponent The exponent of the floating point representation. function unpack(PackedFloat packed) internal pure returns (int256 signedCoefficient, int256 exponent) { - uint256 mask = type(uint128).max; + uint256 mask = type(uint224).max; assembly ("memory-safe") { - signedCoefficient := signextend(0x0F, and(packed, mask)) - exponent := sar(0x80, packed) + signedCoefficient := signextend(27, and(packed, mask)) + exponent := sar(0xe0, packed) } } diff --git a/src/lib/implementation/LibDecimalFloatImplementation.sol b/src/lib/implementation/LibDecimalFloatImplementation.sol index 0f5fa789..dbbca078 100644 --- a/src/lib/implementation/LibDecimalFloatImplementation.sol +++ b/src/lib/implementation/LibDecimalFloatImplementation.sol @@ -13,17 +13,17 @@ import {LibDecimalFloat} from "../LibDecimalFloat.sol"; error WithTargetExponentOverflow(int256 signedCoefficient, int256 exponent, int256 targetExponent); -/// @dev The minimum exponent that can be normalized. -/// This is crazy small, so should never be a problem for any real use case. -/// We need it to guard against overflow when normalizing. -int256 constant EXPONENT_MIN = type(int128).min + 79; - /// @dev The maximum exponent that can be normalized. /// This is crazy large, so should never be a problem for any real use case. /// We need it to guard against overflow when normalizing. -int256 constant EXPONENT_MAX = type(int128).max - 78; +int256 constant EXPONENT_MAX = type(int256).max / 2; int256 constant EXPONENT_MAX_PLUS_ONE = EXPONENT_MAX + 1; +/// @dev The minimum exponent that can be normalized. +/// This is crazy small, so should never be a problem for any real use case. +/// 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. diff --git a/test/src/lib/LibDecimalFloat.divide.t.sol b/test/src/lib/LibDecimalFloat.divide.t.sol index 335e66cd..89bdc631 100644 --- a/test/src/lib/LibDecimalFloat.divide.t.sol +++ b/test/src/lib/LibDecimalFloat.divide.t.sol @@ -2,7 +2,7 @@ pragma solidity =0.8.25; import {THREES, ONES} from "../../lib/LibCommonResults.sol"; -import {LibDecimalFloat, EXPONENT_MIN, EXPONENT_MAX, Float} from "src/lib/LibDecimalFloat.sol"; +import {LibDecimalFloat, Float, EXPONENT_MIN, EXPONENT_MAX} from "src/lib/LibDecimalFloat.sol"; import {Test} from "forge-std/Test.sol"; @@ -120,8 +120,8 @@ contract LibDecimalFloatDivideTest is Test { /// forge-config: default.fuzz.runs = 100 function testUnnormalizedThreesDivision0(int256 exponentA, int256 exponentB) external pure { - exponentA = bound(exponentA, EXPONENT_MIN, EXPONENT_MAX); - exponentB = bound(exponentB, EXPONENT_MIN, EXPONENT_MAX); + exponentA = bound(exponentA, EXPONENT_MIN / 2, EXPONENT_MAX / 2); + exponentB = bound(exponentB, EXPONENT_MIN / 2, EXPONENT_MAX / 2); int256 d = 3; int256 di = 0; diff --git a/test/src/lib/LibDecimalFloat.inv.t.sol b/test/src/lib/LibDecimalFloat.inv.t.sol index ca9e95f6..f258b3bb 100644 --- a/test/src/lib/LibDecimalFloat.inv.t.sol +++ b/test/src/lib/LibDecimalFloat.inv.t.sol @@ -2,7 +2,7 @@ pragma solidity =0.8.25; import {Test} from "forge-std/Test.sol"; -import {LibDecimalFloat, EXPONENT_MIN, EXPONENT_MAX, Float} from "src/lib/LibDecimalFloat.sol"; +import {LibDecimalFloat, Float, EXPONENT_MIN, EXPONENT_MAX} from "src/lib/LibDecimalFloat.sol"; import {LibDecimalFloatSlow} from "test/lib/LibDecimalFloatSlow.sol"; contract LibDecimalFloatInvTest is Test { diff --git a/test/src/lib/LibDecimalFloat.minus.t.sol b/test/src/lib/LibDecimalFloat.minus.t.sol index d75cc471..ae9f2e0a 100644 --- a/test/src/lib/LibDecimalFloat.minus.t.sol +++ b/test/src/lib/LibDecimalFloat.minus.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.25; -import {LibDecimalFloat, EXPONENT_MIN, EXPONENT_MAX, Float} from "src/lib/LibDecimalFloat.sol"; +import {LibDecimalFloat, Float, EXPONENT_MIN, EXPONENT_MAX} from "src/lib/LibDecimalFloat.sol"; import {LibDecimalFloatImplementation} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; import {Test} from "forge-std/Test.sol"; diff --git a/test/src/lib/LibDecimalFloat.multiply.t.sol b/test/src/lib/LibDecimalFloat.multiply.t.sol index 2cc26626..572e72a6 100644 --- a/test/src/lib/LibDecimalFloat.multiply.t.sol +++ b/test/src/lib/LibDecimalFloat.multiply.t.sol @@ -5,13 +5,11 @@ import { LibDecimalFloat, NORMALIZED_ZERO_SIGNED_COEFFICIENT, NORMALIZED_ZERO_EXPONENT, - Float -} from "src/lib/LibDecimalFloat.sol"; -import { + Float, EXPONENT_MIN, - EXPONENT_MAX, - LibDecimalFloatImplementation -} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; + EXPONENT_MAX +} from "src/lib/LibDecimalFloat.sol"; +import {LibDecimalFloatImplementation} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; import {LibDecimalFloatSlow} from "test/lib/LibDecimalFloatSlow.sol"; import {Test} from "forge-std/Test.sol"; diff --git a/test/src/lib/LibDecimalFloat.pack.t.sol b/test/src/lib/LibDecimalFloat.pack.t.sol index 47da73ac..d8131d40 100644 --- a/test/src/lib/LibDecimalFloat.pack.t.sol +++ b/test/src/lib/LibDecimalFloat.pack.t.sol @@ -1,14 +1,7 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.25; -import { - LibDecimalFloat, - ExponentOverflow, - EXPONENT_MIN, - EXPONENT_MAX, - PackedFloat, - Float -} from "src/lib/LibDecimalFloat.sol"; +import {LibDecimalFloat, ExponentOverflow, PackedFloat, Float, EXPONENT_MAX} from "src/lib/LibDecimalFloat.sol"; import {LibDecimalFloatImplementation} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; import {Test} from "forge-std/Test.sol"; @@ -30,24 +23,34 @@ contract LibDecimalFloatPackTest is Test { } /// Round trip from/to parts. - function testPartsRoundTrip(int128 signedCoefficient, int128 exponent) external pure { + function testPartsRoundTrip(int224 signedCoefficient, int32 exponent) external pure { PackedFloat packed = LibDecimalFloat.pack(signedCoefficient, exponent); (int256 signedCoefficientOut, int256 exponentOut) = LibDecimalFloat.unpack(packed); assertEq(signedCoefficient, signedCoefficientOut, "coefficient"); - assertEq(exponent, exponentOut, "exponent"); + if (signedCoefficient != 0) { + assertEq(exponent, exponentOut, "exponent"); + } else { + // 0 exponent is always 0. + assertEq(exponentOut, 0, "exponent"); + } } - /// Can round trip any normalized number. - function testNormalizedRoundTrip(int256 signedCoefficient, int256 exponent) external pure { - exponent = bound(exponent, EXPONENT_MIN, EXPONENT_MAX); - (signedCoefficient, exponent) = LibDecimalFloatImplementation.normalize(signedCoefficient, exponent); + /// Can round trip any normalized number provided the exponent is in range. + function testNormalizedRoundTrip(int256 signedCoefficient, int32 exponent) external pure { + (int256 signedCoefficientNormalized, int256 exponentNormalized) = + LibDecimalFloatImplementation.normalize(signedCoefficient, exponent); + vm.assume(int32(exponentNormalized) == exponentNormalized); - PackedFloat packed = LibDecimalFloat.pack(signedCoefficient, exponent); - (int256 signedCoefficientOut, int256 exponentOut) = LibDecimalFloat.unpack(packed); + PackedFloat packed = LibDecimalFloat.pack(signedCoefficientNormalized, exponentNormalized); + (int256 signedCoefficientUnpacked, int256 exponentUnpacked) = LibDecimalFloat.unpack(packed); - assertEq(signedCoefficient, signedCoefficientOut, "coefficient"); - assertEq(exponent, exponentOut, "exponent"); + assertTrue( + LibDecimalFloat.eq( + signedCoefficientNormalized, exponentNormalized, signedCoefficientUnpacked, exponentUnpacked + ), + "eq" + ); } /// Mem and stack versions behave the same for pack. diff --git a/test/src/lib/LibDecimalFloat.power10.t.sol b/test/src/lib/LibDecimalFloat.power10.t.sol index 414057e9..d326c371 100644 --- a/test/src/lib/LibDecimalFloat.power10.t.sol +++ b/test/src/lib/LibDecimalFloat.power10.t.sol @@ -1,11 +1,9 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.25; -import {LibDecimalFloat, EXPONENT_MIN, Float} from "src/lib/LibDecimalFloat.sol"; +import {LibDecimalFloat, Float} from "src/lib/LibDecimalFloat.sol"; import {LogTest} from "../../abstract/LogTest.sol"; -import {console2} from "forge-std/Test.sol"; - contract LibDecimalFloatPower10Test is LogTest { using LibDecimalFloat for Float; @@ -40,11 +38,8 @@ contract LibDecimalFloatPower10Test is LogTest { int256 expectedExponent ) internal { address tables = logTables(); - uint256 a = gasleft(); (int256 actualSignedCoefficient, int256 actualExponent) = LibDecimalFloat.power10(tables, signedCoefficient, exponent); - uint256 b = gasleft(); - console2.log("%d %d Gas used: %d", uint256(signedCoefficient), uint256(exponent), a - b); assertEq(actualSignedCoefficient, expectedSignedCoefficient, "signedCoefficient"); assertEq(actualExponent, expectedExponent, "exponent"); } diff --git a/test/src/lib/LibDecimalFloat.sub.t.sol b/test/src/lib/LibDecimalFloat.sub.t.sol index 6ecf578b..e57078ea 100644 --- a/test/src/lib/LibDecimalFloat.sub.t.sol +++ b/test/src/lib/LibDecimalFloat.sub.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.25; -import {LibDecimalFloat, EXPONENT_MIN, EXPONENT_MAX, Float} from "src/lib/LibDecimalFloat.sol"; +import {LibDecimalFloat, Float, EXPONENT_MIN, EXPONENT_MAX} from "src/lib/LibDecimalFloat.sol"; import {LibDecimalFloatImplementation} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; import {Test} from "forge-std/Test.sol"; diff --git a/test/src/lib/parse/LibParseDecimalFloat.t.sol b/test/src/lib/parse/LibParseDecimalFloat.t.sol index 19e4e4a2..4e59443c 100644 --- a/test/src/lib/parse/LibParseDecimalFloat.t.sol +++ b/test/src/lib/parse/LibParseDecimalFloat.t.sol @@ -37,6 +37,7 @@ contract LibParseDecimalFloatTest is Test { try this.parseDecimalFloatExternal(data) returns ( bytes4 errorSelector, uint256 cursorAfter, int256 signedCoefficient, int256 exponent ) { + (cursorAfter); (bytes4 errorSelectorMem, Float memory float) = this.parseDecimalFloatExternalMem(data); assertEq(errorSelector, errorSelectorMem, "Error selector mismatch"); assertEq(signedCoefficient, float.signedCoefficient, "Signed coefficient mismatch");