Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed Float16 from Float64 and BigFloat #42837

Merged
merged 7 commits into from
Nov 4, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fix nextfloat 0.0
  • Loading branch information
oscardssmith committed Nov 1, 2021
commit 41533ef17cde7e618327399446d5cb90d2b3acad
5 changes: 4 additions & 1 deletion base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,10 @@ function Float16(x::BigFloat) :: Float16
if (resi&0x7fffffff) < 0x38800000 # if Float16(res) is subnormal
#shift so that the mantissa lines up where it would for normal Float16
shift = 113-((resi & 0x7f800000)>>23)
shift<23 && (resi >>= shift)
if shift<23
resi |= 0x0080_0000 # set implicit bit
resi >>= shift
end
end
if (resi & 0x1fff == 0x1000) # if we are halfway between 2 Float16 values
vchuravy marked this conversation as resolved.
Show resolved Hide resolved
# adjust the value by 1 ULP in the direction that will make Float16(res) give the right answer
Expand Down
4 changes: 3 additions & 1 deletion src/runtime_intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,10 @@ JL_DLLEXPORT uint16_t __truncdfhf2(double param)
if ((resi&0x7fffffffu) < 0x38800000u){ // if Float16(res) is subnormal
// shift so that the mantissa lines up where it would for normal Float16
uint32_t shift = 113u-((resi & 0x7f800000u)>>23u);
if (shift<23u)
if (shift<23u) {
resi |= 0x00800000; // set implicit bit
resi >>= shift;
}
}
if ((resi & 0x1fffu) == 0x1000u) { // if we are halfway between 2 Float16 values
memcpy(&resi, &res, sizeof(res));
Expand Down
5 changes: 2 additions & 3 deletions test/float16.jl
Original file line number Diff line number Diff line change
Expand Up @@ -209,16 +209,15 @@ const minsubf16_32 = Float32(minsubf16)
for i in 1:2^16
f = reinterpret(Float16, UInt16(i-1))
isfinite(f) || continue
abs(f)<=eps(f) && continue
if f < 0
epsdown = T(eps(f))/2
epsup = issubnormal(f) ? epsdown : T(eps(nextfloat(f)))/2
else
epsup = T(eps(f))/2
epsdown = issubnormal(f) ? epsup : T(eps(prevfloat(f)))/2
end
@test isequal(f, Float16(nextfloat(T(f) - epsdown)))
@test isequal(f, Float16(prevfloat(T(f) + epsup)))
@test isequal(f*(-1)^(f === Float16(0)), Float16(nextfloat(T(f) - epsdown)))
@test isequal(f*(-1)^(f === -Float16(0)), Float16(prevfloat(T(f) + epsup)))
@test isequal(prevfloat(f), Float16(prevfloat(T(f) - epsdown)))
@test isequal(nextfloat(f), Float16(nextfloat(T(f) + epsup)))
end
Expand Down