Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:19
erlang
3243-Print-large-bignums-in-base-16-instead-of-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 3243-Print-large-bignums-in-base-16-instead-of-in-interna.patch of Package erlang
From b3038094d5d15ef66fb76ae370208f1d3665a668 Mon Sep 17 00:00:00 2001 From: Rickard Green <rickard@erlang.org> Date: Fri, 8 Jan 2021 16:53:51 +0100 Subject: [PATCH 3/3] Print large bignums in base 16 instead of in internal representation --- lib/erl_interface/src/misc/ei_printterm.c | 47 +++++++++++++++++------ lib/erl_interface/test/ei_print_SUITE.erl | 43 ++++++--------------- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/lib/erl_interface/src/misc/ei_printterm.c b/lib/erl_interface/src/misc/ei_printterm.c index 3a464377b1..0bad730095 100644 --- a/lib/erl_interface/src/misc/ei_printterm.c +++ b/lib/erl_interface/src/misc/ei_printterm.c @@ -90,6 +90,7 @@ static char *ei_big_to_str(erlang_big *b) unsigned int no_digits; unsigned short *sp; int i; + int printed; /* Number of 16-bit digits */ no_digits = (b->arity + 1) / 2; @@ -110,26 +111,48 @@ static char *ei_big_to_str(erlang_big *b) return buf; } + /* big nums this large gets printed in base 16... */ buf_len = (!!b->is_neg /* "-" */ - + 9 /* "#integer(" */ - + 10 /* %d */ - + 5 /* ") = {" */ - + 6*no_digits /* 16-bit digits + ","s */ - + 1 /* "}" */ + + 3 /* "16#" */ + + 4*no_digits /* 16-bit digits in base 16 */ + 1); /* \0 */ if ( (buf=malloc(buf_len)) == NULL) return NULL; s = buf; if ( b->is_neg ) - s += sprintf(s,"-"); + *(s++) = '-'; + *(s++) = '1'; + *(s++) = '6'; + *(s++) = '#'; + + sp = b->digits; + printed = 0; + for (i = no_digits - 1; i >= 0; i--) { + unsigned short val = sp[i]; + int j; + + for (j = 3; j >= 0; j--) { + char c = (char) ((val >> (j*4)) & 0xf); + if (c < 10) + c += '0'; + else + c += 'A' - 10; + + if (printed) + *(s++) = c; + else if (c != '0') { + *(s++) = c; + printed = !0; + } + } + } - s += sprintf(s,"#integer(%d) = {", no_digits); - for(sp = b->digits, i = 0; i < no_digits; i++) { - s += sprintf(s, "%d", (int) sp[i]); - if (i + 1 != no_digits) - *(s++) = ','; + if (!printed) { + /* very strange to encode zero like this... */ + *(s++) = '0'; } - *(s++) = '}'; + + *s = '\0'; return buf; } diff --git a/lib/erl_interface/test/ei_print_SUITE.erl b/lib/erl_interface/test/ei_print_SUITE.erl index c0c2b40891..43d74066a2 100644 --- a/lib/erl_interface/test/ei_print_SUITE.erl +++ b/lib/erl_interface/test/ei_print_SUITE.erl @@ -216,6 +216,8 @@ integers(Config) -> test_integers(Port, 16#feeddeaddeadbeef - 1000, 16#feeddeaddeadbeef + 1000), test_integers(Port, -16#feeddeaddeadbeef - 1000, -16#feeddeaddeadbeef + 1000), test_integers(Port, (1 bsl 64) - 1000, (1 bsl 64) + 1000), + test_integers(Port, 16#addfeeddeaddeadbeef - 1000, 16#addfeeddeaddeadbeef + 1000), + test_integers(Port, -16#addfeeddeaddeadbeef - 1000, -16#addfeeddeaddeadbeef + 1000), test_integers(Port, -(1 bsl 64) - 1000, -(1 bsl 64) + 1000), test_integers(Port, (1 bsl 8192) - 1000, (1 bsl 8192) + 1000), test_integers(Port, -(1 bsl 8192) - 1000, -(1 bsl 8192) + 1000), @@ -228,19 +230,21 @@ integers(Config) -> test_integer(Port, Int, Print) when is_integer(Int) -> Res = send_term_get_printed(Port, Int), - Exp = try - _ = list_to_integer(Res), - integer_to_list(Int) - catch - _:_ -> - bignum_string(Int) - end, case Print of true -> io:format("Res: ~s~n", [Res]); false -> ok end, + %% Large bignums are printed in base 16... + Exp = case Res of + "16#" ++ _ -> + "16#" ++ integer_to_list(Int, 16); + "-16#" ++ _ -> + "-16#" ++ integer_to_list(-1*Int, 16); + _ -> + integer_to_list(Int) + end, case Exp =:= Res of true -> ok; @@ -249,33 +253,10 @@ test_integer(Port, Int, Print) when is_integer(Int) -> ct:fail({Exp, Res}) end. -bignum_string(Int) -> - {AbsInt, Sign} = case Int < 0 of - true -> {-1*Int, "-"}; - false -> {Int, ""} - end, - Digits = bignum_digits(AbsInt, []), - NoDigits = length(Digits), - lists:flatten([Sign, "#integer(", - integer_to_list(NoDigits), - ") = {", - lists:foldl(fun (Digit, []) -> - [integer_to_list(Digit), $}]; - (Digit, Acc) -> - [integer_to_list(Digit), $, | Acc] - end, - [], - Digits)]). - -bignum_digits(0, Acc) -> - Acc; -bignum_digits(Int, Acc) -> - bignum_digits(Int bsr 16, [Int band 16#ffff | Acc]). - test_integers(Port, FromInt, ToInt) -> test_integers(Port, FromInt, ToInt, true). -test_integers(Port, FromInt, ToInt, _Print) when FromInt > ToInt -> +test_integers(_Port, FromInt, ToInt, _Print) when FromInt > ToInt -> ok; test_integers(Port, FromInt, ToInt, Print) -> ok = test_integer(Port, FromInt, Print), -- 2.26.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor