From feda5aba6257826de36af401f011fe759f3e93da Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Wed, 30 Jul 2025 16:37:45 +0200 Subject: [PATCH 1/2] any negative power is an error --- test/src/lib/LibDecimalFloat.pow.t.sol | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/test/src/lib/LibDecimalFloat.pow.t.sol b/test/src/lib/LibDecimalFloat.pow.t.sol index 76da2cd5..bf0cf872 100644 --- a/test/src/lib/LibDecimalFloat.pow.t.sol +++ b/test/src/lib/LibDecimalFloat.pow.t.sol @@ -4,7 +4,8 @@ pragma solidity =0.8.25; import {LogTest} from "../../abstract/LogTest.sol"; import {LibDecimalFloat, Float} from "src/lib/LibDecimalFloat.sol"; -import {ZeroNegativePower} from "src/error/ErrDecimalFloat.sol"; +import {ZeroNegativePower, Log10Negative} from "src/error/ErrDecimalFloat.sol"; +import {LibDecimalFloatImplementation} from "src/lib/implementation/LibDecimalFloatImplementation.sol"; import {console2} from "forge-std/Test.sol"; contract LibDecimalFloatPowTest is LogTest { @@ -42,6 +43,24 @@ contract LibDecimalFloatPowTest is LogTest { // // Issues found in fuzzing from here. checkPow(99999, 0, 12182, 0, 1000, 60907); checkPow(1785215562, 0, 18, 0, 3388, 163); + // checkPow(-13479973333575319897333507543169532969897633747806911633120036913154, 539, -13479973333575319897333507543509815336818572211270286240551805119725, -846, 1, 1); + } + + function testNegativePowError(Float a, Float b) external { + // We can't simply minus 0 to get a negative base. + vm.assume(!a.isZero()); + // Anything to 0 power is 1, including negative base. + vm.assume(!b.isZero()); + if (a.gt(LibDecimalFloat.FLOAT_ZERO)) { + 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) + ); + this.powExternal(a, b); } /// a^0 = 1 for all a including 0^0. From f19a3226dc61f679eba293cabc550f377a5b4cfd Mon Sep 17 00:00:00 2001 From: thedavidmeister Date: Wed, 30 Jul 2025 16:40:16 +0200 Subject: [PATCH 2/2] lint --- test/src/lib/LibDecimalFloat.pow.t.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/src/lib/LibDecimalFloat.pow.t.sol b/test/src/lib/LibDecimalFloat.pow.t.sol index bf0cf872..518c8609 100644 --- a/test/src/lib/LibDecimalFloat.pow.t.sol +++ b/test/src/lib/LibDecimalFloat.pow.t.sol @@ -43,9 +43,11 @@ contract LibDecimalFloatPowTest is LogTest { // // Issues found in fuzzing from here. checkPow(99999, 0, 12182, 0, 1000, 60907); checkPow(1785215562, 0, 18, 0, 3388, 163); - // checkPow(-13479973333575319897333507543169532969897633747806911633120036913154, 539, -13479973333575319897333507543509815336818572211270286240551805119725, -846, 1, 1); } + /// a^b is error for negative a and all b. + /// In the future we may support negative bases with integer exponents. + /// https://github.com/rainlanguage/rain.math.float/issues/88 function testNegativePowError(Float a, Float b) external { // We can't simply minus 0 to get a negative base. vm.assume(!a.isZero());