Skip to content

rem returns zero for negative float input on ARMv7 #134

@kimikage

Description

@kimikage

To check the modification for the issue #129, I ran the tests on a 32-bit ARMv7 system (RPi 2 Model B v1.2). And then, I faced a problem with rem (%).

modulus: Test Failed at ~/.julia/dev/FixedPointNumbers/test/normed.jl:148
  Expression: (-0.3 % N0f8).i == round(Int, -0.3 * 255) % UInt8
   Evaluated: 0x00 == 0xb4
modulus: Test Failed at ~/.julia/dev/FixedPointNumbers/test/normed.jl:154
  Expression: (-0.3 % N6f10).i == round(Int, -0.3 * 1023) % UInt16
   Evaluated: 0x0000 == 0xfecd

The cause is the behavior of unsafe_trunc.

rem(x::Real, ::Type{T}) where {T <: Normed} = reinterpret(T, _unsafe_trunc(rawtype(T), round(rawone(T)*x)))

_unsafe_trunc(::Type{T}, x::Integer) where {T} = x % T
_unsafe_trunc(::Type{T}, x) where {T} = unsafe_trunc(T, x)

julia> versioninfo()
Julia Version 1.0.3
Platform Info:
  OS: Linux (arm-linux-gnueabihf)
  CPU: ARMv7 Processor rev 4 (v7l)
  WORD_SIZE: 32
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, cortex-a53)

julia> unsafe_trunc(UInt8, -76.0) # or the intrinsic `fptoui`
0x00

julia> unsafe_trunc(Int8, -76.0)
-76

julia> unsafe_trunc(UInt8, unsafe_trunc(Int8, -76.0))
0xb4

(The problem occurs not only on v1.0.3 but also on v1.0.5 and v1.2.0. I have not tried the 64-bit.)

Although the behavior of unsafe_trunc may not be what we want, this is not a bug.

If the value is not representable by T, an arbitrary value will be returned.

https://docs.julialang.org/en/v1/base/math/#Base.unsafe_trunc

However, I don't think it is good to make the rem users aware of the internal unsafe_trunc.
The workaround is to convert the value to Signed temporarily as shown above.

BTW, the behavior of Normed's rem, which is specified by the above tests seems to be not intuitive. (Since I know the inside of Normed, I think the behavior is reasonable, though.)
So, I think it is another option to eliminate the tests for negative float inputs, i.e. make it an undefined behavior.

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