diff --git a/.gas-snapshot b/.gas-snapshot index 3b6021b..02f7091 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -1,36 +1,36 @@ -DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5096, μ: 3622499, ~: 3622438) -DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5096, μ: 3627945, ~: 3628019) -DecimalFloatCeilTest:testCeilDeployed(bytes32) (runs: 5096, μ: 3622503, ~: 3622101) -DecimalFloatConstantsTest:testEDeployed() (gas: 3621631) -DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 3621620) -DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 3621621) -DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 3621596) -DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 3621597) -DecimalFloatConstantsTest:testZeroDeployed() (gas: 3621664) -DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5096, μ: 3629575, ~: 3629709) -DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5096, μ: 3622830, ~: 3622756) -DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5096, μ: 3622291, ~: 3622099) -DecimalFloatFormatTest:testFormatDeployed(bytes32,uint256) (runs: 5096, μ: 3648201, ~: 3652804) -DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5096, μ: 3622685, ~: 3622649) -DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5096, μ: 3623268, ~: 3623217) -DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5096, μ: 3623745, ~: 3623684) -DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5096, μ: 3622770, ~: 3622698) -DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5096, μ: 3622761, ~: 3622684) -DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5096, μ: 3627984, ~: 3628033) -DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5096, μ: 3621941, ~: 3621941) -DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5096, μ: 3622747, ~: 3622675) -DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5096, μ: 3622804, ~: 3622728) -DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5096, μ: 3622813, ~: 3622750) -DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5096, μ: 3622808, ~: 3622748) -DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5096, μ: 3622606, ~: 3622607) -DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5096, μ: 3626529, ~: 3627316) +DecimalFloatAbsTest:testAbsDeployed(bytes32) (runs: 5096, μ: 3611684, ~: 3611622) +DecimalFloatAddTest:testAddDeployed(bytes32,bytes32) (runs: 5096, μ: 3617219, ~: 3617323) +DecimalFloatCeilTest:testCeilDeployed(bytes32) (runs: 5096, μ: 3611687, ~: 3611285) +DecimalFloatConstantsTest:testEDeployed() (gas: 3610815) +DecimalFloatConstantsTest:testMaxNegativeValueDeployed() (gas: 3610804) +DecimalFloatConstantsTest:testMaxPositiveValueDeployed() (gas: 3610805) +DecimalFloatConstantsTest:testMinNegativeValueDeployed() (gas: 3610780) +DecimalFloatConstantsTest:testMinPositiveValueDeployed() (gas: 3610781) +DecimalFloatConstantsTest:testZeroDeployed() (gas: 3610848) +DecimalFloatDivTest:testDivDeployed(bytes32,bytes32) (runs: 5096, μ: 3618767, ~: 3618901) +DecimalFloatEqTest:testEqDeployed(bytes32,bytes32) (runs: 5096, μ: 3612016, ~: 3611940) +DecimalFloatFloorTest:testFloorDeployed(bytes32) (runs: 5096, μ: 3611475, ~: 3611283) +DecimalFloatFormatTest:testFormatDeployed(bytes32,uint256) (runs: 5096, μ: 3637333, ~: 3641988) +DecimalFloatFracTest:testFracDeployed(bytes32) (runs: 5096, μ: 3611869, ~: 3611833) +DecimalFloatFromFixedDecimalLosslessTest:testFromFixedDecimalLosslessDeployed(uint256,uint8) (runs: 5096, μ: 3612455, ~: 3612401) +DecimalFloatFromFixedDecimalLossyTest:testFromFixedDecimalLossyDeployed(uint256,uint8) (runs: 5096, μ: 3612932, ~: 3612868) +DecimalFloatGtTest:testGtDeployed(bytes32,bytes32) (runs: 5096, μ: 3611954, ~: 3611882) +DecimalFloatGteTest:testGteDeployed(bytes32,bytes32) (runs: 5096, μ: 3611941, ~: 3611868) +DecimalFloatInvTest:testInvDeployed(bytes32) (runs: 5096, μ: 3617158, ~: 3617217) +DecimalFloatIsZeroTest:testIsZeroDeployed(bytes32) (runs: 5096, μ: 3611125, ~: 3611125) +DecimalFloatLtTest:testLtDeployed(bytes32,bytes32) (runs: 5096, μ: 3611931, ~: 3611859) +DecimalFloatLteTest:testLteDeployed(bytes32,bytes32) (runs: 5096, μ: 3611985, ~: 3611912) +DecimalFloatMaxTest:testMaxDeployed(bytes32,bytes32) (runs: 5096, μ: 3611994, ~: 3611934) +DecimalFloatMinTest:testMinDeployed(bytes32,bytes32) (runs: 5096, μ: 3611992, ~: 3611932) +DecimalFloatMinusTest:testMinusDeployed(bytes32) (runs: 5096, μ: 3611790, ~: 3611791) +DecimalFloatMulTest:testMulDeployed(bytes32,bytes32) (runs: 5096, μ: 3615714, ~: 3616500) DecimalFloatPackLosslessTest:testPackDeployed(int224,int32) (runs: 5096, μ: 170044, ~: 170045) -DecimalFloatParseTest:testParseDeployed(string) (runs: 5096, μ: 3625179, ~: 3625048) -DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5096, μ: 3675640, ~: 3651855) -DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5096, μ: 3639347, ~: 3640641) -DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5096, μ: 3628369, ~: 3628394) -DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5096, μ: 3623883, ~: 3623780) -DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5096, μ: 3623973, ~: 3624264) +DecimalFloatParseTest:testParseDeployed(string) (runs: 5096, μ: 3614363, ~: 3614232) +DecimalFloatPowTest:testPowDeployed(bytes32,bytes32) (runs: 5096, μ: 3663866, ~: 3641157) +DecimalFloatSqrtTest:testSqrtDeployed(bytes32) (runs: 5096, μ: 3628101, ~: 3629825) +DecimalFloatSubTest:testSubDeployed(bytes32,bytes32) (runs: 5096, μ: 3617533, ~: 3617568) +DecimalFloatToFixedDecimalLosslessTest:testToFixedDecimalLosslessDeployed(bytes32,uint8) (runs: 5096, μ: 3613070, ~: 3612964) +DecimalFloatToFixedDecimalLossyTest:testToFixedDecimalLossyDeployed(bytes32,uint8) (runs: 5096, μ: 3613141, ~: 3613448) LibDecimalFloatAbsTest:testAbsMinValue(int32) (runs: 5038, μ: 5162, ~: 5162) LibDecimalFloatAbsTest:testAbsNegative(int256,int32) (runs: 5096, μ: 10536, ~: 10754) LibDecimalFloatAbsTest:testAbsNonNegative(int256,int32) (runs: 5096, μ: 9700, ~: 9316) @@ -210,8 +210,8 @@ LibDecimalFloatImplementationMulTest:testMulZeroAnyExponent(int64,int64) (runs: LibDecimalFloatImplementationMulTest:testMulZeroOne() (gas: 4438) LibDecimalFloatImplementationPow10Test:testExactLookupsPow10() (gas: 1287338) LibDecimalFloatImplementationPow10Test:testExactPows() (gas: 1258404) -LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1290143) -LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 3594, μ: 1255821, ~: 1253779) +LibDecimalFloatImplementationPow10Test:testInterpolatedLookupsPower() (gas: 1290173) +LibDecimalFloatImplementationPow10Test:testNoRevert(int224,int32) (runs: 3637, μ: 1256004, ~: 1253800) LibDecimalFloatImplementationPow10Test:testPow10One() (gas: 1563766) LibDecimalFloatImplementationSubTest:testSubIsAdd(int256,int256,int256,int256) (runs: 5079, μ: 17124, ~: 17237) LibDecimalFloatImplementationSubTest:testSubMinSignedValue(int256,int256,int256) (runs: 5096, μ: 15937, ~: 15910) @@ -289,19 +289,19 @@ LibDecimalFloatPackTest:testPackExponentOverflow(int256,int256) (runs: 5046, μ: LibDecimalFloatPackTest:testPackNegativeExponentLossyZero(int256,int256) (runs: 5046, μ: 11957, ~: 12110) LibDecimalFloatPackTest:testPackZero(int256) (runs: 5096, μ: 4469, ~: 4469) LibDecimalFloatPackTest:testPartsRoundTrip(int224,int32) (runs: 5096, μ: 5484, ~: 5485) -LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5096, μ: 1640522, ~: 1254643) -LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5047, μ: 1241606, ~: 1241724) -LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 3513, μ: 1240754, ~: 1240754) -LibDecimalFloatPowTest:testPowAZeroNegative(bytes32) (runs: 1604, μ: 1241138, ~: 1241138) -LibDecimalFloatPowTest:testPowBOne(bytes32) (runs: 5081, μ: 1545717, ~: 1545688) +LibDecimalFloatPow10Test:testPow10Packed(bytes32) (runs: 5096, μ: 1642228, ~: 1254685) +LibDecimalFloatPowTest:testNegativePowError(bytes32,bytes32) (runs: 5052, μ: 1241606, ~: 1241724) +LibDecimalFloatPowTest:testPowAZero(int32,bytes32) (runs: 3539, μ: 1240754, ~: 1240754) +LibDecimalFloatPowTest:testPowAZeroNegative(bytes32) (runs: 1617, μ: 1241138, ~: 1241138) +LibDecimalFloatPowTest:testPowBOne(bytes32) (runs: 5065, μ: 1545718, ~: 1545688) LibDecimalFloatPowTest:testPowBZero(bytes32,int32) (runs: 5096, μ: 1240322, ~: 1240322) -LibDecimalFloatPowTest:testPows() (gas: 1672051) -LibDecimalFloatPowTest:testRoundTripFuzzPow(bytes32,bytes32) (runs: 5096, μ: 1286713, ~: 1261888) -LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1881202) -LibDecimalFloatSqrtTest:testRoundTripFuzzSqrt(int224,int32) (runs: 5096, μ: 1305156, ~: 1310935) -LibDecimalFloatSqrtTest:testSqrt() (gas: 1304231) -LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5074, μ: 1241319, ~: 1241437) -LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1522848) +LibDecimalFloatPowTest:testPows() (gas: 1697700) +LibDecimalFloatPowTest:testRoundTripFuzzPow(bytes32,bytes32) (runs: 5096, μ: 1292479, ~: 1262284) +LibDecimalFloatPowTest:testRoundTripSimple() (gas: 1881282) +LibDecimalFloatSqrtTest:testRoundTripFuzzSqrt(int224,int32) (runs: 5097, μ: 1303876, ~: 1306645) +LibDecimalFloatSqrtTest:testSqrt() (gas: 1304251) +LibDecimalFloatSqrtTest:testSqrtNegative(bytes32) (runs: 5069, μ: 1241319, ~: 1241437) +LibDecimalFloatSqrtTest:testSqrtRoundTrip() (gas: 1522878) LibDecimalFloatSubTest:testSubPacked(bytes32,bytes32) (runs: 5096, μ: 12228, ~: 12283) LibFormatDecimalFloatCountSigFigs:testCountSigFigsExamples() (gas: 83596) LibFormatDecimalFloatCountSigFigs:testCountSigFigsOne(int256) (runs: 5096, μ: 31877, ~: 31719) diff --git a/src/lib/implementation/LibDecimalFloatImplementation.sol b/src/lib/implementation/LibDecimalFloatImplementation.sol index 30ea6be..5212a27 100644 --- a/src/lib/implementation/LibDecimalFloatImplementation.sol +++ b/src/lib/implementation/LibDecimalFloatImplementation.sol @@ -888,14 +888,17 @@ library LibDecimalFloatImplementation { lookupAntilogTableY1Y2(tablesDataContract, uint256(idx), interpolate); } if (interpolate) { - // This case causes an overflow below. - if (idx > 4 && scale == 1e76) { - scale = 1e75; - mantissaCoefficient /= 10; + // This avoids a potential overflow below. + int256 idxPlus1 = (idx + 1); + unchecked { + while ((idxPlus1 * scale) / scale != idxPlus1) { + scale /= 10; + mantissaCoefficient /= 10; + } } (signedCoefficient, exponent) = unitLinearInterpolation( - idx * scale, mantissaCoefficient, (idx + 1) * scale, exponent, y1Coefficient, y2Coefficient, -4 + idx * scale, mantissaCoefficient, idxPlus1 * scale, exponent, y1Coefficient, y2Coefficient, -4 ); } else { signedCoefficient = y1Coefficient; diff --git a/test/src/lib/LibDecimalFloat.pow.t.sol b/test/src/lib/LibDecimalFloat.pow.t.sol index d0b7266..3782f8d 100644 --- a/test/src/lib/LibDecimalFloat.pow.t.sol +++ b/test/src/lib/LibDecimalFloat.pow.t.sol @@ -71,6 +71,7 @@ contract LibDecimalFloatPowTest is LogTest { } checkPow(1.0029e67, -67, 0.41e2, -2, 1.001e3, -3); + checkPow(96001e62, -62, 0.00115e5, -5, 1.014e3, -3); } /// a^b is error for negative a and all b.