Skip to content

rem(::Float128, ::Float128) uses round-to-nearest instead of truncated #112

Description

@langestefan

Base.rem for Float128 uses libquadmath's remainderq:

Quadmath.jl/src/Quadmath.jl

Lines 330 to 331 in 9f739ce

@assume_effects :foldable Base.rem(x::Float128, y::Float128) =
Float128(@quad_ccall(libquadmath.remainderq(x::Cfloat128, y::Cfloat128)::Cfloat128))

Which implements round-to-nearest quotient. Julia's rem uses truncated division, round-to-zero.

This leads to inconsistencies in computations that use Base.rem, such as sind, cosd, tand.

MWE

julia> using Quadmath

julia> rem(Float128(7.5), Float128(2))
-0.5   # expected 1.5

julia> rem(7.5, 2.0)   # Float64 reference
1.5

julia> rem(Float128(200), Float128(360))
-160   # expected 200.0

Fix

Call fmodq instead of remainderq.

If we want to also support the current behaviour, remainderq corresponds toBase.rem(x, y, RoundNearest), which could be added as a separate method.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions