Skip to content

Commit e54d83e

Browse files
floor fix
1 parent 44e0ac4 commit e54d83e

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

‎src/lib/LibDecimalFloat.sol‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ library LibDecimalFloat {
582582
return result;
583583
}
584584

585-
/// Integer component of a float.
585+
/// Smallest integer value less than or equal to the float.
586586
/// @param float The float to floor.
587587
function floor(Float float) internal pure returns (Float) {
588588
(int256 signedCoefficient, int256 exponent) = float.unpack();
@@ -592,6 +592,11 @@ library LibDecimalFloat {
592592
}
593593
(int256 characteristic, int256 mantissa) =
594594
LibDecimalFloatImplementation.characteristicMantissa(signedCoefficient, exponent);
595+
if (signedCoefficient < 0 && mantissa < 0) {
596+
// If the float is negative and has a fractional part, we need to
597+
// subtract 1 from the characteristic to floor it.
598+
(characteristic, exponent) = LibDecimalFloatImplementation.sub(characteristic, exponent, 1e76, -76);
599+
}
595600
(Float result, bool lossless) = packLossy(characteristic, exponent);
596601
// Flooring is lossy by definition.
597602
(lossless, mantissa);

‎test/src/lib/LibDecimalFloat.floor.t.sol‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,43 @@ contract LibDecimalFloatFloorTest is Test {
4747
/// Examples
4848
function testFloorExamples() external pure {
4949
checkFloor(123456789, 0, 123456789, 0);
50+
checkFloor(-123456789, 0, -123456789, 0);
51+
checkFloor(-1234567890, -1, -1234567890, -1);
52+
5053
checkFloor(123456789, -1, 123456780, -1);
54+
checkFloor(-123456789, -1, -12345679e60, -60);
55+
checkFloor(12345678900, -2, 12345678900, -2);
56+
5157
checkFloor(123456789, -2, 123456700, -2);
58+
checkFloor(-123456789, -2, -1234568e61, -61);
59+
5260
checkFloor(123456789, -3, 123456000, -3);
61+
checkFloor(-123456789, -3, -123457e62, -62);
62+
5363
checkFloor(123456789, -4, 123450000, -4);
64+
checkFloor(-123456789, -4, -12346e63, -63);
65+
5466
checkFloor(123456789, -5, 123400000, -5);
67+
checkFloor(-123456789, -5, -1235e64, -64);
68+
5569
checkFloor(123456789, -6, 123000000, -6);
70+
checkFloor(-123456789, -6, -124e65, -65);
71+
5672
checkFloor(123456789, -7, 120000000, -7);
73+
checkFloor(-123456789, -7, -13e66, -66);
74+
5775
checkFloor(123456789, -8, 100000000, -8);
76+
checkFloor(-123456789, -8, -2e66, -66);
77+
5878
checkFloor(123456789, -9, 0, 0);
79+
checkFloor(-123456789, -9, -1e67, -67);
80+
5981
checkFloor(123456789, -10, 0, 0);
82+
checkFloor(-123456789, -10, -1e67, -67);
83+
6084
checkFloor(123456789, -11, 0, 0);
85+
checkFloor(-123456789, -11, -1e67, -67);
86+
6187
checkFloor(type(int224).max, 0, type(int224).max, 0);
6288
checkFloor(type(int224).min, 0, type(int224).min, 0);
6389

0 commit comments

Comments
 (0)