From a3c4877dfd882a06d5d6eaa3af5247cc3c505194 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 21 Mar 2025 11:48:49 -0400 Subject: [PATCH 1/4] fix `mod` for mixes of `Signed` and `Unsigned` Previously this was just overfowing producing wrong answers (both for the sign convention and just the wrong modulo class) fixes https://github.com/JuliaLang/julia/issues/57851 --- base/int.jl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/base/int.jl b/base/int.jl index 38cbe366bd7ce..e46d518183d7a 100644 --- a/base/int.jl +++ b/base/int.jl @@ -286,8 +286,14 @@ function mod(x::T, y::T) where T<:Integer y == -1 && return T(0) # avoid potential overflow in fld return x - fld(x, y) * y end -mod(x::BitSigned, y::Unsigned) = rem(y + unsigned(rem(x, y)), y) -mod(x::Unsigned, y::Signed) = rem(y + signed(rem(x, y)), y) +function mod(x::BitSigned, y::Unsigned) + remval = rem(x, y) # correct iff x>0 or remval==0 + return remval + (!iszero(remval) && x0 so correct iff y>0 or remval==0 + return remval + (!iszero(remval) && y Date: Fri, 21 Mar 2025 12:30:56 -0400 Subject: [PATCH 2/4] add test --- test/int.jl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/int.jl b/test/int.jl index dda736cd7a9d0..715625cf8b6d9 100644 --- a/test/int.jl +++ b/test/int.jl @@ -362,6 +362,23 @@ end end end end + # exhaustive UInt8/Int8 tests for mixed signedness + for f in (mod, rem) + for i in -128:127 + for j in 0:255 + if iszero(i) + @test_throws DivideError f(UInt8(j), Int8(i)) + else + @test f(UInt8(j), Int8(i)) == f(j, i) + end + if iszero(j) + @test_throws DivideError f(Int8(i), UInt8(j)) + else + @test f(Int8(i), UInt8(j)) == f(i,j) + end + end + end + end end @testset "Underscores in big_str" begin From 32713ddb4b279d7ce6234d9b558d3145f8286cdf Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Fri, 21 Mar 2025 12:31:42 -0400 Subject: [PATCH 3/4] simplify slightly --- base/int.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/int.jl b/base/int.jl index e46d518183d7a..042d29d8abdbe 100644 --- a/base/int.jl +++ b/base/int.jl @@ -287,8 +287,8 @@ function mod(x::T, y::T) where T<:Integer return x - fld(x, y) * y end function mod(x::BitSigned, y::Unsigned) - remval = rem(x, y) # correct iff x>0 or remval==0 - return remval + (!iszero(remval) && x=0 + return remval + (remval0 so correct iff y>0 or remval==0 From d579285a3cb2b3dc8dbb0a212f3b984699f8c489 Mon Sep 17 00:00:00 2001 From: Oscar Smith Date: Sat, 22 Mar 2025 14:47:59 -0400 Subject: [PATCH 4/4] fix types --- base/int.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/int.jl b/base/int.jl index 042d29d8abdbe..2d7bede4fac69 100644 --- a/base/int.jl +++ b/base/int.jl @@ -288,7 +288,7 @@ function mod(x::T, y::T) where T<:Integer end function mod(x::BitSigned, y::Unsigned) remval = rem(x, y) # correct iff remval>=0 - return remval + (remval0 so correct iff y>0 or remval==0