aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/num_bif_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/num_bif_SUITE.erl')
-rw-r--r--erts/emulator/test/num_bif_SUITE.erl268
1 files changed, 268 insertions, 0 deletions
diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl
new file mode 100644
index 0000000000..d009994e2d
--- /dev/null
+++ b/erts/emulator/test/num_bif_SUITE.erl
@@ -0,0 +1,268 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(num_bif_SUITE).
+
+-include("test_server.hrl").
+
+%% Tests the BIFs:
+%% abs/1
+%% float/1
+%% float_to_list/1
+%% integer_to_list/1
+%% list_to_float/1
+%% list_to_integer/1
+%% round/1
+%% trunc/1
+
+-export([all/1, t_abs/1, t_float/1,
+ t_float_to_list/1, t_integer_to_list/1,
+ t_list_to_integer/1,
+ t_list_to_float/1, t_list_to_float_safe/1, t_list_to_float_risky/1,
+ t_round/1, t_trunc/1]).
+
+all(suite) -> [t_abs, t_float, t_float_to_list, t_integer_to_list,
+ t_list_to_float, t_list_to_integer,
+ t_round, t_trunc].
+
+t_abs(Config) when is_list(Config) ->
+ %% Floats.
+ ?line 5.5 = abs(id(5.5)),
+ ?line 0.0 = abs(id(0.0)),
+ ?line 100.0 = abs(id(-100.0)),
+
+ %% Integers.
+ ?line 5 = abs(id(5)),
+ ?line 0 = abs(id(0)),
+ ?line 100 = abs(id(-100)),
+
+ %% The largest smallnum. OTP-3190.
+ ?line X = id((1 bsl 27) - 1),
+ ?line X = abs(X),
+ ?line X = abs(X-1)+1,
+ ?line X = abs(X+1)-1,
+ ?line X = abs(-X),
+ ?line X = abs(-X-1)-1,
+ ?line X = abs(-X+1)+1,
+
+ %% Bignums.
+ BigNum = id(13984792374983749),
+ ?line BigNum = abs(BigNum),
+ ?line BigNum = abs(-BigNum),
+ ok.
+
+t_float(Config) when is_list(Config) ->
+ ?line 0.0 = float(id(0)),
+ ?line 2.5 = float(id(2.5)),
+ ?line 0.0 = float(id(0.0)),
+ ?line -100.55 = float(id(-100.55)),
+ ?line 42.0 = float(id(42)),
+ ?line -100.0 = float(id(-100)),
+
+ %% Bignums.
+ ?line 4294967305.0 = float(id(4294967305)),
+ ?line -4294967305.0 = float(id(-4294967305)),
+
+ %% Extremly big bignums.
+ ?line Big = id(list_to_integer(id(lists:duplicate(2000, $1)))),
+ ?line {'EXIT', {badarg, _}} = (catch float(Big)),
+
+ %% Invalid types and lists.
+ ?line {'EXIT', {badarg, _}} = (catch list_to_integer(id(atom))),
+ ?line {'EXIT', {badarg, _}} = (catch list_to_integer(id(123))),
+ ?line {'EXIT', {badarg, _}} = (catch list_to_integer(id([$1,[$2]]))),
+ ?line {'EXIT', {badarg, _}} = (catch list_to_integer(id("1.2"))),
+ ?line {'EXIT', {badarg, _}} = (catch list_to_integer(id("a"))),
+ ?line {'EXIT', {badarg, _}} = (catch list_to_integer(id(""))),
+ ok.
+
+
+%% Tests float_to_list/1.
+
+t_float_to_list(Config) when is_list(Config) ->
+ ?line test_ftl("0.0e+0", 0.0),
+ ?line test_ftl("2.5e+1", 25.0),
+ ?line test_ftl("2.5e+0", 2.5),
+ ?line test_ftl("2.5e-1", 0.25),
+ ?line test_ftl("-3.5e+17", -350.0e15),
+ ok.
+
+test_ftl(Expect, Float) ->
+ %% No ?line on the next line -- we want the line number from t_float_to_list.
+ Expect = remove_zeros(lists:reverse(float_to_list(Float)), []).
+
+%% Removes any non-significant zeros in a floating point number.
+%% Example: 2.500000e+01 -> 2.5e+1
+
+remove_zeros([$+, $e|Rest], [$0, X|Result]) ->
+ remove_zeros([$+, $e|Rest], [X|Result]);
+remove_zeros([$-, $e|Rest], [$0, X|Result]) ->
+ remove_zeros([$-, $e|Rest], [X|Result]);
+remove_zeros([$0, $.|Rest], [$e|Result]) ->
+ remove_zeros(Rest, [$., $0, $e|Result]);
+remove_zeros([$0|Rest], [$e|Result]) ->
+ remove_zeros(Rest, [$e|Result]);
+remove_zeros([Char|Rest], Result) ->
+ remove_zeros(Rest, [Char|Result]);
+remove_zeros([], Result) ->
+ Result.
+
+%% Tests integer_to_list/1.
+
+t_integer_to_list(Config) when is_list(Config) ->
+ ?line "0" = integer_to_list(id(0)),
+ ?line "42" = integer_to_list(id(42)),
+ ?line "-42" = integer_to_list(id(-42)),
+ ?line "32768" = integer_to_list(id(32768)),
+ ?line "268435455" = integer_to_list(id(268435455)),
+ ?line "-268435455" = integer_to_list(id(-268435455)),
+ ?line "123456932798748738738" = integer_to_list(id(123456932798748738738)),
+ ?line Big_List = id(lists:duplicate(2000, id($1))),
+ ?line Big = list_to_integer(Big_List),
+ ?line Big_List = integer_to_list(Big),
+ ok.
+
+%% Tests list_to_float/1.
+
+t_list_to_float(suite) -> [t_list_to_float_safe, t_list_to_float_risky].
+
+t_list_to_float_safe(Config) when is_list(Config) ->
+ ?line 0.0 = list_to_float(id("0.0")),
+ ?line 0.0 = list_to_float(id("-0.0")),
+ ?line 0.5 = list_to_float(id("0.5")),
+ ?line -0.5 = list_to_float(id("-0.5")),
+ ?line 100.0 = list_to_float(id("1.0e2")),
+ ?line 127.5 = list_to_float(id("127.5")),
+ ?line -199.5 = list_to_float(id("-199.5")),
+
+ ?line {'EXIT',{badarg,_}} = (catch list_to_float(id("0"))),
+ ?line {'EXIT',{badarg,_}} = (catch list_to_float(id("0..0"))),
+ ?line {'EXIT',{badarg,_}} = (catch list_to_float(id("0e12"))),
+ ?line {'EXIT',{badarg,_}} = (catch list_to_float(id("--0.0"))),
+
+ ok.
+
+%% This might crash the emulator...
+%% (Known to crash the Unix version of Erlang 4.4.1)
+
+t_list_to_float_risky(Config) when is_list(Config) ->
+ ?line Many_Ones = lists:duplicate(25000, id($1)),
+ ?line id(list_to_float("2."++Many_Ones)),
+ ?line {'EXIT', {badarg, _}} = (catch list_to_float("2"++Many_Ones)),
+ ok.
+
+%% Tests list_to_integer/1.
+
+t_list_to_integer(Config) when is_list(Config) ->
+ ?line 0 = list_to_integer(id("0")),
+ ?line 0 = list_to_integer(id("00")),
+ ?line 0 = list_to_integer(id("-0")),
+ ?line 1 = list_to_integer(id("1")),
+ ?line -1 = list_to_integer(id("-1")),
+ ?line 42 = list_to_integer(id("42")),
+ ?line -12 = list_to_integer(id("-12")),
+ ?line 32768 = list_to_integer(id("32768")),
+ ?line 268435455 = list_to_integer(id("268435455")),
+ ?line -268435455 = list_to_integer(id("-268435455")),
+
+ %% Bignums.
+ ?line 123456932798748738738 = list_to_integer(id("123456932798748738738")),
+ ?line id(list_to_integer(lists:duplicate(2000, id($1)))),
+ ok.
+
+%% Tests round/1.
+
+t_round(Config) when is_list(Config) ->
+ ?line 0 = round(id(0.0)),
+ ?line 0 = round(id(0.4)),
+ ?line 1 = round(id(0.5)),
+ ?line 0 = round(id(-0.4)),
+ ?line -1 = round(id(-0.5)),
+ ?line 255 = round(id(255.3)),
+ ?line 256 = round(id(255.6)),
+ ?line -1033 = round(id(-1033.3)),
+ ?line -1034 = round(id(-1033.6)),
+
+ % OTP-3722:
+ ?line X = id((1 bsl 27) - 1),
+ ?line MX = -X,
+ ?line MXm1 = -X-1,
+ ?line MXp1 = -X+1,
+ ?line F = id(X + 0.0),
+ ?line X = round(F),
+ ?line X = round(F+1)-1,
+ ?line X = round(F-1)+1,
+ ?line MX = round(-F),
+ ?line MXm1 = round(-F-1),
+ ?line MXp1 = round(-F+1),
+
+ ?line X = round(F+0.1),
+ ?line X = round(F+1+0.1)-1,
+ ?line X = round(F-1+0.1)+1,
+ ?line MX = round(-F+0.1),
+ ?line MXm1 = round(-F-1+0.1),
+ ?line MXp1 = round(-F+1+0.1),
+
+ ?line X = round(F-0.1),
+ ?line X = round(F+1-0.1)-1,
+ ?line X = round(F-1-0.1)+1,
+ ?line MX = round(-F-0.1),
+ ?line MXm1 = round(-F-1-0.1),
+ ?line MXp1 = round(-F+1-0.1),
+
+ ?line 0.5 = abs(round(F+0.5)-(F+0.5)),
+ ?line 0.5 = abs(round(F-0.5)-(F-0.5)),
+ ?line 0.5 = abs(round(-F-0.5)-(-F-0.5)),
+ ?line 0.5 = abs(round(-F+0.5)-(-F+0.5)),
+
+ %% Bignums.
+ ?line 4294967296 = round(id(4294967296.1)),
+ ?line 4294967297 = round(id(4294967296.9)),
+ ?line -4294967296 = -round(id(4294967296.1)),
+ ?line -4294967297 = -round(id(4294967296.9)),
+ ok.
+
+t_trunc(Config) when is_list(Config) ->
+ ?line 0 = trunc(id(0.0)),
+ ?line 5 = trunc(id(5.3333)),
+ ?line -10 = trunc(id(-10.978987)),
+
+ % The largest smallnum, converted to float (OTP-3722):
+ ?line X = id((1 bsl 27) - 1),
+ ?line F = id(X + 0.0),
+ io:format("X = ~p/~w/~w, F = ~p/~w/~w, trunc(F) = ~p/~w/~w~n",
+ [X, X, binary_to_list(term_to_binary(X)),
+ F, F, binary_to_list(term_to_binary(F)),
+ trunc(F), trunc(F), binary_to_list(term_to_binary(trunc(F)))]),
+ ?line X = trunc(F),
+ ?line X = trunc(F+1)-1,
+ ?line X = trunc(F-1)+1,
+ ?line X = -trunc(-F),
+ ?line X = -trunc(-F-1)-1,
+ ?line X = -trunc(-F+1)+1,
+
+ %% Bignums.
+ ?line 4294967305 = trunc(id(4294967305.7)),
+ ?line -4294967305 = trunc(id(-4294967305.7)),
+ ok.
+
+% Calling this function (which is not supposed to be inlined) prevents
+% the compiler from calculating the answer, so we don't test the compiler
+% instead of the newest runtime system.
+id(X) -> X.