Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed a bug where negative or oversized segment sizes were not rejected in binary matching
- Fixed the `network` mdns configuration to read the documented `host` key; the previously
required, undocumented `hostname` key is still accepted
- Fixed `rem` returning wrong results on 32-bit builds when an operand is a big integer with
a 64-bit magnitude, such as `(1 bsl 63) rem 7`

## [0.7.0-alpha.1] - 2026-04-06

Expand Down
5 changes: 2 additions & 3 deletions src/libAtomVM/bif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,7 @@ static term rem_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, t
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
}
if (term_is_boxed_integer(arg2)) {
size |= term_boxed_size(arg2);
size = MAX(size, (int) term_boxed_size(arg2));
} else if (UNLIKELY(!term_is_integer(arg2))) {
TRACE("error: arg1: 0x%lx, arg2: 0x%lx\n", arg1, arg2);
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
Expand All @@ -1466,8 +1466,7 @@ static term rem_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, t
}

#if BOXED_TERMS_REQUIRED_FOR_INT64 == 2
case 2:
case 3: {
case 2: {
avm_int64_t val1 = term_maybe_unbox_int64(arg1);
avm_int64_t val2 = term_maybe_unbox_int64(arg2);
if (UNLIKELY(val2 == 0)) {
Expand Down
19 changes: 19 additions & 0 deletions tests/erlang_tests/bigint.erl
Original file line number Diff line number Diff line change
Expand Up @@ -259,8 +259,27 @@ test_rem() ->
),
<<"E3AE0EA63AE33EA79B071316BC9A7F1B">> = erlang:integer_to_binary(Int8 rem Int9, 16),

% operands with a 64-bit magnitude take 3 boxed terms on 32-bit builds and
% must not be mistaken for regular 2-term boxed int64 values
Int10 = erlang:binary_to_integer(?MODULE:id(<<"8000000000000000">>), 16),
Int11 = erlang:binary_to_integer(?MODULE:id(<<"8000000000000005">>), 16),
Int12 = erlang:binary_to_integer(?MODULE:id(<<"-8000000000000001">>), 16),
Int13 = erlang:binary_to_integer(?MODULE:id(<<"FFFFFFFFFFFFFFFF">>), 16),
Int14 = erlang:binary_to_integer(?MODULE:id(<<"7FFFFFFFFFFFFFFF">>), 16),

1 = Int10 rem ?MODULE:id(7),
808 = Int10 rem ?MODULE:id(1000),
8 = Int10 rem ?MODULE:id(1073741825),
-2 = Int12 rem ?MODULE:id(7),
5 = ?MODULE:id(5) rem Int13,
5 = Int13 rem ?MODULE:id(10),
42 = ?MODULE:id(42) rem Int10,
<<"7FFFFFFFFFFFFFFF">> = erlang:integer_to_binary(Int14 rem Int11, 16),
<<"8000000000000000">> = erlang:integer_to_binary(Int10 rem Int11, 16),

ok = expect_error(badarith, fun() -> Int0 rem ?MODULE:id(0) end),
ok = expect_error(badarith, fun() -> Int1 rem ?MODULE:id(0) end),
ok = expect_error(badarith, fun() -> Int10 rem ?MODULE:id(0) end),

0.

Expand Down
Loading