Skip to content

Commit b62e8ce

Browse files
authored
Backport "Fix _unsafe_trunc to reduce the likelihood of arbitrary values (#291)" (#301)
1 parent a995a9d commit b62e8ce

File tree

3 files changed

+16
-35
lines changed

3 files changed

+16
-35
lines changed

src/utilities.jl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,17 @@ exponent_bias(::Type{Float32}) = 127
3838
exponent_bias(::Type{Float64}) = 1023
3939

4040
_unsafe_trunc(::Type{T}, x::Integer) where {T} = x % T
41-
_unsafe_trunc(::Type{T}, x) where {T} = unsafe_trunc(T, x)
42-
if !signbit(signed(unsafe_trunc(UInt, -12.345)))
43-
# a workaround for ARM (issue #134)
44-
function _unsafe_trunc(::Type{T}, x::AbstractFloat) where {T <: Integer}
45-
unsafe_trunc(T, unsafe_trunc(signedtype(T), x))
41+
_unsafe_trunc(::Type{T}, x) where {T} = unsafe_trunc(T, x)
42+
# issue #202, #211
43+
_unsafe_trunc(::Type{T}, x::BigFloat) where {T <: Integer} = trunc(BigInt, x) % T
44+
45+
# issue #288
46+
function _unsafe_trunc(::Type{T}, x::AbstractFloat) where {T <: Integer}
47+
if T <: ShortInts
48+
return unsafe_trunc(Int32, x) % T
49+
elseif T <: Unsigned
50+
return copysign(unsafe_trunc(T, abs(x)), x)
51+
else
52+
return unsafe_trunc(T, x)
4653
end
47-
# exclude BigFloat (issue #202)
48-
_unsafe_trunc(::Type{T}, x::BigFloat) where {T <: Integer} = unsafe_trunc(T, x)
4954
end

test/fixed.jl

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,8 @@ end
2525
issue288_out = String(take!(buf))
2626

2727
@testset "issue288" begin
28-
expected_issue288 = "-1.0Q0f7 -1.0Q0f15 -1.0Q0f15 -1.0Q0f7 "
29-
if issue288_in == expected_issue288 # just leave it in the report
30-
@test issue288_in == expected_issue288
31-
else
32-
@test_broken issue288_in == expected_issue288
33-
@warn """broken: "$issue288_in"\nexpected: "$expected_issue288" """
34-
end
35-
expected_issue288 = "-1.0Q0f7 -1.0Q0f15 -1.0Q0f15 -1.0Q0f7 "
36-
if issue288_out == expected_issue288 # just leave it in the report
37-
@test issue288_out == expected_issue288
38-
else
39-
@test_broken issue288_out == expected_issue288
40-
@warn """broken: "$issue288_out"\nexpected: "$expected_issue288" """
41-
end
28+
@test issue288_in == "-1.0Q0f7 -1.0Q0f15 -1.0Q0f15 -1.0Q0f7 "
29+
@test issue288_out == "-1.0Q0f7 -1.0Q0f15 -1.0Q0f15 -1.0Q0f7 "
4230
end
4331

4432
function test_op(fun::F, ::Type{T}, fx, fy, fxf, fyf, tol) where {F,T}

test/normed.jl

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,8 @@ end
2525
issue288_out = String(take!(buf))
2626

2727
@testset "issue288" begin
28-
expected_issue288 = "1.0N0f8 1.0N0f16 1.0N0f16 1.0N0f8 "
29-
if issue288_in == expected_issue288 # just leave it in the report
30-
@test issue288_in == expected_issue288
31-
else
32-
@test_broken issue288_in == expected_issue288
33-
@warn """broken: "$issue288_in"\nexpected: "$expected_issue288" """
34-
end
35-
expected_issue288 = "0.004N0f8 2.0e-5N0f16 2.0e-5N0f16 0.004N0f8 "
36-
if issue288_out == expected_issue288 # just leave it in the report
37-
@test issue288_out == expected_issue288
38-
else
39-
@test_broken issue288_out == expected_issue288
40-
@warn """broken: "$issue288_out"\nexpected: "$expected_issue288" """
41-
end
28+
@test issue288_in == "1.0N0f8 1.0N0f16 1.0N0f16 1.0N0f8 "
29+
@test issue288_out == "0.004N0f8 2.0e-5N0f16 2.0e-5N0f16 0.004N0f8 "
4230
end
4331

4432
@testset "domain of f" begin

0 commit comments

Comments
 (0)