Skip to content

Commit c60d126

Browse files
committed
Merge pull request #1518 from jakub-gonet/jgonet/float-1-avm
Add float/1 BIF See also #1509 These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents afdecae + 8c519cd commit c60d126

File tree

7 files changed

+79
-0
lines changed

7 files changed

+79
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424
- Added `lists:append/1` and `lists:append/2`
2525
- Added `erlang:spawn_monitor/1`, `erlang:spawn_monitor/3`
2626
- Added `lists:dropwhile/2`.
27+
- Support for `float/1` BIF.
2728

2829
### Fixed
2930
- ESP32: improved sntp sync speed from a cold boot.

src/libAtomVM/bif.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,27 @@ term bif_erlang_trunc_1(Context *ctx, uint32_t fail_label, int live, term arg1)
12011201
}
12021202
}
12031203

1204+
term bif_erlang_float_1(Context *ctx, uint32_t fail_label, int live, term arg1)
1205+
{
1206+
if (term_is_float(arg1)) {
1207+
return arg1;
1208+
}
1209+
1210+
if (!term_is_any_integer(arg1)) {
1211+
RAISE_ERROR_BIF(fail_label, BADARG_ATOM);
1212+
}
1213+
1214+
avm_float_t fresult = term_conv_to_float(arg1);
1215+
if (UNLIKELY(!isfinite(fresult))) {
1216+
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
1217+
}
1218+
1219+
if (UNLIKELY(memory_ensure_free_with_roots(ctx, FLOAT_SIZE, live, ctx->x, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
1220+
RAISE_ERROR_BIF(fail_label, OUT_OF_MEMORY_ATOM);
1221+
}
1222+
return term_from_float(fresult, &ctx->heap);
1223+
}
1224+
12041225
typedef int64_t (*bitwise_op)(int64_t a, int64_t b);
12051226

12061227
static inline term bitwise_helper(Context *ctx, uint32_t fail_label, int live, term arg1, term arg2, bitwise_op op)

src/libAtomVM/bif.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ term bif_erlang_ceil_1(Context *ctx, uint32_t fail_label, int live, term arg1);
8282
term bif_erlang_floor_1(Context *ctx, uint32_t fail_label, int live, term arg1);
8383
term bif_erlang_round_1(Context *ctx, uint32_t fail_label, int live, term arg1);
8484
term bif_erlang_trunc_1(Context *ctx, uint32_t fail_label, int live, term arg1);
85+
term bif_erlang_float_1(Context *ctx, uint32_t fail_label, int live, term arg1);
8586

8687
term bif_erlang_bor_2(Context *ctx, uint32_t fail_label, int live, term arg1, term arg2);
8788
term bif_erlang_band_2(Context *ctx, uint32_t fail_label, int live, term arg1, term arg2);

src/libAtomVM/bifs.gperf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ erlang:ceil/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_er
7878
erlang:floor/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_floor_1}
7979
erlang:round/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_round_1}
8080
erlang:trunc/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_trunc_1}
81+
erlang:float/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_float_1}
8182
erlang:bor/2, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif2_ptr = bif_erlang_bor_2}
8283
erlang:band/2, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif2_ptr = bif_erlang_band_2}
8384
erlang:bxor/2, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif2_ptr = bif_erlang_bxor_2}

tests/erlang_tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ compile_erlang(float2bin2scientific)
398398
compile_erlang(float2bin2)
399399
compile_erlang(float2list2decimals)
400400
compile_erlang(float2list2scientific)
401+
compile_erlang(float_bif)
401402
compile_erlang(float2list2)
402403
compile_erlang(bin2float)
403404
compile_erlang(list2float)
@@ -880,6 +881,7 @@ add_custom_target(erlang_test_modules DEPENDS
880881
float2bin2.beam
881882
float2list2decimals.beam
882883
float2list2scientific.beam
884+
float_bif.beam
883885
float2list2.beam
884886
bin2float.beam
885887
list2float.beam

tests/erlang_tests/float_bif.erl

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
%
2+
% This file is part of AtomVM.
3+
%
4+
% Copyright 2025 Jakub Gonet <jakub.gonet@swmansion.com>
5+
%
6+
% Licensed under the Apache License, Version 2.0 (the "License");
7+
% you may not use this file except in compliance with the License.
8+
% You may obtain a copy of the License at
9+
%
10+
% http://www.apache.org/licenses/LICENSE-2.0
11+
%
12+
% Unless required by applicable law or agreed to in writing, software
13+
% distributed under the License is distributed on an "AS IS" BASIS,
14+
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
% See the License for the specific language governing permissions and
16+
% limitations under the License.
17+
%
18+
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
%
20+
21+
-module(float_bif).
22+
23+
-export([start/0]).
24+
% For remote function calls
25+
-export([id/1, check_one/1]).
26+
27+
-define(ID(Arg), ?MODULE:id(Arg)).
28+
29+
start() ->
30+
true = 1.0 =:= float(?ID(1)),
31+
true = 1.0 =:= float(?ID(1.0)),
32+
ok =
33+
try float(?ID("1")) of
34+
_ ->
35+
unreachable
36+
catch
37+
error:badarg ->
38+
ok
39+
end,
40+
ok = ?MODULE:check_one(?ID(1)),
41+
ok = ?MODULE:check_one(?ID(1.0)),
42+
error = ?MODULE:check_one(?ID(atom)),
43+
0.
44+
45+
id(X) ->
46+
X.
47+
48+
% Tests float/1 in guards
49+
check_one(T) when float(T) =:= 1.0 ->
50+
ok;
51+
check_one(_T) ->
52+
error.

tests/test.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ struct Test tests[] = {
447447
TEST_CASE_EXPECTED(float2bin2decimals, 255),
448448
TEST_CASE_EXPECTED(float2bin2, 31),
449449
TEST_CASE_EXPECTED(float2list2scientific, 31),
450+
TEST_CASE(float_bif),
450451
TEST_CASE_EXPECTED(float2list2decimals, 255),
451452
TEST_CASE_EXPECTED(float2list2, 31),
452453
TEST_CASE_EXPECTED(bin2float, 511),

0 commit comments

Comments
 (0)