@@ -1272,6 +1272,123 @@ end
12721272 end
12731273end
12741274
1275+ @testset " round_with_overflow" begin
1276+ using FixedPointDecimals: round_with_overflow
1277+
1278+ FD642 = FixedDecimal{Int64,2 }
1279+ FD643 = FixedDecimal{Int64,3 }
1280+
1281+ # Is alias for `ceil`.
1282+ @testset " up" begin
1283+ @test round_with_overflow (FD642 (- 0.51 ), RoundUp) === (FD642 (0 ), false )
1284+ @test round_with_overflow (FD642 (- 0.50 ), RoundUp) === (FD642 (0 ), false )
1285+ @test round_with_overflow (FD642 (- 0.49 ), RoundUp) === (FD642 (0 ), false )
1286+ @test round_with_overflow (FD642 (0.50 ), RoundUp) === (FD642 (1 ), false )
1287+ @test round_with_overflow (FD642 (0.51 ), RoundUp) === (FD642 (1 ), false )
1288+ @test round_with_overflow (FD642 (1.50 ), RoundUp) === (FD642 (2 ), false )
1289+ @test round_with_overflow (typemin (FD642), RoundUp) ===
1290+ (parse (FD642, " -92233720368547758" ), false )
1291+
1292+ @testset " overflowing" begin
1293+ @test round_with_overflow (typemax (FD642), RoundUp) ===
1294+ (parse (FD642, " -92233720368547757.16" ), true )
1295+ @test round_with_overflow (parse (FD642, " 92233720368547758.01" ), RoundUp) ===
1296+ (parse (FD642, " -92233720368547757.16" ), true )
1297+ end
1298+ end
1299+
1300+ # Is alias for `floor`.
1301+ @testset " down" begin
1302+ @test round_with_overflow (FD642 (- 0.51 ), RoundDown) === (FD642 (- 1 ), false )
1303+ @test round_with_overflow (FD642 (- 0.50 ), RoundDown) === (FD642 (- 1 ), false )
1304+ @test round_with_overflow (FD642 (- 0.49 ), RoundDown) === (FD642 (- 1 ), false )
1305+ @test round_with_overflow (FD642 (0.50 ), RoundDown) === (FD642 (0 ), false )
1306+ @test round_with_overflow (FD642 (0.51 ), RoundDown) === (FD642 (0 ), false )
1307+ @test round_with_overflow (FD642 (1.50 ), RoundDown) === (FD642 (1 ), false )
1308+ @test round_with_overflow (typemax (FD642), RoundDown) ===
1309+ (parse (FD642, " 92233720368547758" ), false )
1310+
1311+ @testset " overflowing" begin
1312+ @test round_with_overflow (typemin (FD642), RoundDown) ===
1313+ (parse (FD642, " 92233720368547757.16" ), true )
1314+ @test round_with_overflow (parse (FD642, " -92233720368547758.01" ), RoundDown) ===
1315+ (parse (FD642, " 92233720368547757.16" ), true )
1316+ end
1317+ end
1318+
1319+ # Is alias for `trunc`.
1320+ @testset " to zero" begin
1321+ @test round_with_overflow (FD642 (- 0.51 ), RoundToZero) === (FD642 (0 ), false )
1322+ @test round_with_overflow (FD642 (- 0.50 ), RoundToZero) === (FD642 (0 ), false )
1323+ @test round_with_overflow (FD642 (- 0.49 ), RoundToZero) === (FD642 (0 ), false )
1324+ @test round_with_overflow (FD642 (0.50 ), RoundToZero) === (FD642 (0 ), false )
1325+ @test round_with_overflow (FD642 (0.51 ), RoundToZero) === (FD642 (0 ), false )
1326+ @test round_with_overflow (FD642 (1.50 ), RoundToZero) === (FD642 (1 ), false )
1327+
1328+ @test round_with_overflow (typemin (FD642), RoundToZero) ===
1329+ (parse (FD642, " -92233720368547758" ), false )
1330+ @test round_with_overflow (typemax (FD642), RoundToZero) ===
1331+ (parse (FD642, " 92233720368547758" ), false )
1332+
1333+ # Cannot overflow.
1334+ end
1335+
1336+ @testset " tie away" begin
1337+ @test round_with_overflow (FD642 (- 0.51 ), RoundNearestTiesAway) === (FD642 (- 1 ), false )
1338+ @test round_with_overflow (FD642 (- 0.50 ), RoundNearestTiesAway) === (FD642 (- 1 ), false )
1339+ @test round_with_overflow (FD642 (- 0.49 ), RoundNearestTiesAway) === (FD642 (0 ), false )
1340+ @test round_with_overflow (FD642 (0.50 ), RoundNearestTiesAway) === (FD642 (1 ), false )
1341+ @test round_with_overflow (FD642 (0.51 ), RoundNearestTiesAway) === (FD642 (1 ), false )
1342+ @test round_with_overflow (FD642 (1.50 ), RoundNearestTiesAway) === (FD642 (2 ), false )
1343+
1344+ @test round_with_overflow (typemin (FD642), RoundNearestTiesAway) ===
1345+ (parse (FD642, " -92233720368547758" ), false )
1346+ @test round_with_overflow (typemax (FD642), RoundNearestTiesAway) ===
1347+ (parse (FD642, " 92233720368547758" ), false )
1348+
1349+ @testset " overflowing" begin
1350+ # For max, FD642 has fractional .07 so use FD643 which has .807.
1351+ @test round_with_overflow (typemin (FD643), RoundNearestTiesAway) ===
1352+ (parse (FD643, " 9223372036854775.616" ), true )
1353+ @test round_with_overflow (typemax (FD643), RoundNearestTiesAway) ===
1354+ (parse (FD643, " -9223372036854775.616" ), true )
1355+
1356+ @test round_with_overflow (parse (FD643, " 9223372036854775.5" ), RoundNearestTiesAway) ===
1357+ (parse (FD643, " -9223372036854775.616" ), true )
1358+ @test round_with_overflow (parse (FD643, " -9223372036854775.5" ), RoundNearestTiesAway) ===
1359+ (parse (FD643, " 9223372036854775.616" ), true )
1360+ end
1361+ end
1362+
1363+ @testset " tie up" begin
1364+ @test round_with_overflow (FD642 (- 0.51 ), RoundNearestTiesUp) === (FD642 (- 1 ), false )
1365+ @test round_with_overflow (FD642 (- 0.50 ), RoundNearestTiesUp) === (FD642 (0 ), false )
1366+ @test round_with_overflow (FD642 (- 0.49 ), RoundNearestTiesUp) === (FD642 (0 ), false )
1367+ @test round_with_overflow (FD642 (0.50 ), RoundNearestTiesUp) === (FD642 (1 ), false )
1368+ @test round_with_overflow (FD642 (0.51 ), RoundNearestTiesUp) === (FD642 (1 ), false )
1369+ @test round_with_overflow (FD642 (1.50 ), RoundNearestTiesUp) === (FD642 (2 ), false )
1370+
1371+ @test round_with_overflow (typemin (FD642), RoundNearestTiesUp) ===
1372+ (parse (FD642, " -92233720368547758" ), false )
1373+ @test round_with_overflow (typemax (FD642), RoundNearestTiesUp) ===
1374+ (parse (FD642, " 92233720368547758" ), false )
1375+
1376+ # For max, FD642 has fractional .07 so use FD643 which has .807.
1377+ @test round_with_overflow (parse (FD643, " -9223372036854775.5" ), RoundNearestTiesUp) ===
1378+ (FD643 (- 9223372036854775 ), false )
1379+
1380+ @testset " overflowing" begin
1381+ @test round_with_overflow (typemin (FD643), RoundNearestTiesUp) ===
1382+ (parse (FD643, " 9223372036854775.616" ), true )
1383+ @test round_with_overflow (typemax (FD643), RoundNearestTiesUp) ===
1384+ (parse (FD643, " -9223372036854775.616" ), true )
1385+
1386+ @test round_with_overflow (parse (FD643, " 9223372036854775.5" ), RoundNearestTiesUp) ===
1387+ (parse (FD643, " -9223372036854775.616" ), true )
1388+ end
1389+ end
1390+ end
1391+
12751392@testset " trunc" begin
12761393 @test trunc (Int, FD2 (0.99 )) === 0
12771394 @test trunc (Int, FD2 (- 0.99 )) === 0
@@ -1420,6 +1537,105 @@ epsi(::Type{T}) where T = eps(T)
14201537 end
14211538end
14221539
1540+ @testset " floor_with_overflow" begin
1541+ using FixedPointDecimals: floor_with_overflow
1542+
1543+ @testset " non-overflowing" begin
1544+ @test floor_with_overflow (FD {Int8,2} (1.02 )) == (FD {Int8,2} (1 ), false )
1545+ @test floor_with_overflow (FD {Int8,2} (- 0.02 )) == (FD {Int8,2} (- 1 ), false )
1546+ @test floor_with_overflow (FD {Int8,2} (- 1 )) == (FD {Int8,2} (- 1 ), false )
1547+
1548+ @test floor_with_overflow (FD {Int16,1} (5.2 )) == (FD {Int16,1} (5 ), false )
1549+ @test floor_with_overflow (FD {Int16,1} (- 5.2 )) == (FD {Int16,1} (- 6 ), false )
1550+
1551+ @test floor_with_overflow (typemax (FD{Int32,0 })) == (typemax (FD{Int32,0 }), false )
1552+ @test floor_with_overflow (typemin (FD{Int32,0 })) == (typemin (FD{Int32,0 }), false )
1553+
1554+ @test floor_with_overflow (FD {Int64,8} (40.054672 )) == (FD {Int64,8} (40 ), false )
1555+ @test floor_with_overflow (FD {Int64,8} (- 40.054672 )) == (FD {Int64,8} (- 41 ), false )
1556+ @test floor_with_overflow (FD {Int64,8} (- 92233720368 )) ==
1557+ (FD {Int64,8} (- 92233720368 ), false )
1558+
1559+ @test floor_with_overflow (typemax (FD{Int128,18 })) ==
1560+ (FD {Int128,18} (170141183460469231731 ), false )
1561+ @test floor_with_overflow (FD {Int128,18} (- 400.0546798232 )) ==
1562+ (FD {Int128,18} (- 401 ), false )
1563+ end
1564+
1565+ @testset " overflowing" begin
1566+ @test floor_with_overflow (typemin (FD{Int8,2 })) == (FD {Int8,2} (0.56 ), true )
1567+ @test floor_with_overflow (FD {Int8,2} (- 1.02 )) == (FD {Int8,2} (0.56 ), true )
1568+
1569+ @test floor_with_overflow (typemin (FD{Int16,3 })) == (FD {Int16,3} (32.536 ), true )
1570+ @test floor_with_overflow (FD {Int16,3} (- 32.111 )) == (FD {Int16,3} (32.536 ), true )
1571+
1572+ @test floor_with_overflow (typemin (FD{Int32,1 })) == (FD {Int32,1} (214748364.6 ), true )
1573+ @test floor_with_overflow (FD {Int32,1} (- 214748364.7 )) ==
1574+ (FD {Int32,1} (214748364.6 ), true )
1575+
1576+ @test floor_with_overflow (typemin (FD{Int64,8 })) ==
1577+ (parse (FD{Int64,8 }, " 92233720368.09551616" ), true )
1578+ @test floor_with_overflow (FD {Int64,8} (- 92233720368.5 )) ==
1579+ (parse (FD{Int64,8 }, " 92233720368.09551616" ), true )
1580+
1581+ @test floor_with_overflow (typemin (FD{Int128,2 })) ==
1582+ (parse (FD{Int128,2 }, " 1701411834604692317316873037158841056.56" ), true )
1583+ @test floor_with_overflow (parse (FD{Int128,2 }, " -1701411834604692317316873037158841057.27" )) ==
1584+ (parse (FD{Int128,2 }, " 1701411834604692317316873037158841056.56" ), true )
1585+ end
1586+ end
1587+
1588+ @testset " ceil_with_overflow" begin
1589+ using FixedPointDecimals: ceil_with_overflow
1590+
1591+ @testset " non-overflowing" begin
1592+ @test ceil_with_overflow (FD {Int8,2} (- 1.02 )) == (FD {Int8,2} (- 1 ), false )
1593+ @test ceil_with_overflow (FD {Int8,2} (- 0.02 )) == (FD {Int8,2} (0 ), false )
1594+ @test ceil_with_overflow (FD {Int8,2} (0.49 )) == (FD {Int8,2} (1 ), false )
1595+ @test ceil_with_overflow (FD {Int8,2} (1 )) == (FD {Int8,2} (1 ), false )
1596+
1597+ @test ceil_with_overflow (FD {Int16,1} (5.2 )) == (FD {Int16,1} (6 ), false )
1598+ @test ceil_with_overflow (FD {Int16,1} (- 5.2 )) == (FD {Int16,1} (- 5 ), false )
1599+
1600+ @test ceil_with_overflow (typemax (FD{Int32,0 })) == (typemax (FD{Int32,0 }), false )
1601+ @test ceil_with_overflow (typemin (FD{Int32,0 })) == (typemin (FD{Int32,0 }), false )
1602+
1603+ @test ceil_with_overflow (FD {Int64,8} (40.054672 )) == (FD {Int64,8} (41 ), false )
1604+ @test ceil_with_overflow (FD {Int64,8} (- 40.054672 )) == (FD {Int64,8} (- 40 ), false )
1605+ @test ceil_with_overflow (FD {Int64,8} (- 92233720368 )) ==
1606+ (FD {Int64,8} (- 92233720368 ), false )
1607+ @test ceil_with_overflow (FD {Int64,8} (92233720368 )) ==
1608+ (FD {Int64,8} (92233720368 ), false )
1609+
1610+ @test ceil_with_overflow (typemin (FD{Int128,18 })) ==
1611+ (FD {Int128,18} (- 170141183460469231731 ), false )
1612+ @test ceil_with_overflow (FD {Int128,18} (- 400.0546798232 )) ==
1613+ (FD {Int128,18} (- 400 ), false )
1614+ end
1615+
1616+ @testset " overflowing" begin
1617+ @test ceil_with_overflow (typemax (FD{Int8,2 })) == (FD {Int8,2} (- 0.56 ), true )
1618+ @test ceil_with_overflow (FD {Int8,2} (1.02 )) == (FD {Int8,2} (- 0.56 ), true )
1619+
1620+ @test ceil_with_overflow (typemax (FD{Int16,3 })) == (FD {Int16,3} (- 32.536 ), true )
1621+ @test ceil_with_overflow (FD {Int16,3} (32.111 )) == (FD {Int16,3} (- 32.536 ), true )
1622+
1623+ @test ceil_with_overflow (typemax (FD{Int32,1 })) == (FD {Int32,1} (- 214748364.6 ), true )
1624+ @test ceil_with_overflow (FD {Int32,1} (214748364.7 )) ==
1625+ (FD {Int32,1} (- 214748364.6 ), true )
1626+
1627+ @test ceil_with_overflow (typemax (FD{Int64,8 })) ==
1628+ (parse (FD{Int64,8 }, " -92233720368.09551616" ), true )
1629+ @test ceil_with_overflow (FD {Int64,8} (92233720368.5 )) ==
1630+ (parse (FD{Int64,8 }, " -92233720368.09551616" ), true )
1631+
1632+ @test ceil_with_overflow (typemax (FD{Int128,2 })) ==
1633+ (parse (FD{Int128,2 }, " -1701411834604692317316873037158841056.56" ), true )
1634+ @test ceil_with_overflow (parse (FD{Int128,2 }, " 1701411834604692317316873037158841057.27" )) ==
1635+ (parse (FD{Int128,2 }, " -1701411834604692317316873037158841056.56" ), true )
1636+ end
1637+ end
1638+
14231639@testset " type stability" begin
14241640 # Test that basic operations are type stable for all the basic integer types.
14251641 fs = [0 , 1 , 2 , 7 , 16 , 38 ] # To save time, don't test all possible combinations.
0 commit comments