Skip to content

[fork-ffi] integers: rem — PureScript/JS rem is the TRUNCATED remainder (result takes the sign… #88

@Unisay

Description

@Unisay

Package: purescript-lua-integers
File: src/Data/Int.lua
Function: rem
Class: semantics Severity: high

PureScript/JS rem is the TRUNCATED remainder (result takes the sign of the dividend): JS does x % y, and in JS % truncates toward zero. Lua's % operator is the FLOORED modulo (result takes the sign of the divisor). They differ for mixed-sign operands: rem (-2) 3 is -2 in PureScript but 1 in Lua; rem 2 (-3) is 2 in PureScript but -1 in Lua. This breaks both the documented examples in Data.Int.purs (rem (-2) 3 == (-2), rem 2 (-3) == 2) and the package's quot/rem law test q*b + r == a for go (-2) 3 and go 2 (-3) (Test/Data/Int.purs lines 170-171): with the current rem, 0*3 + 1 = 1 != -2.

Current (Lua):

rem = (function(x) return function(y) return x % y end end),

Expected: Truncated remainder with the sign of the dividend: rem (-2) 3 == -2, rem 2 (-3) == 2, and q*b + r == a where q = quot x y.

Proposed fix:

rem = (function(x) return function(y)
  if y == 0 then return 0 end
  local q = math.modf(x / y)  -- truncate toward zero, matching quot
  return x - q * y
end end),

Found by the FFI audit; reproduced under Lua 5.1.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions