Re: Problem with binary_to_integer/1 and list_to_integer/1 (QuickCheck test case)

Mikael Pettersson <[email protected]>
Newsgroups gmane.comp.lang.erlang.bugs
Message-ID <[email protected]>
Lukas Larsson writes:
 > Hello Jesper,
 > 
 > There seems to be a bug in the generic c-code for binary/list_to_integer 
 > for that specific value where a bignum is returned when a small should 
 > have been returned. If no-one feels like submitting a patch to fix it, 
 > I'll take a look later this week.

The bug in binary_to_integer is because of a (classic) algorithm
mistake in big.c:erts_chars_to_integer.  That code converts in
unsigned, keeping the representation as fixnum as long as possible,
and only at the very last step negates if the chars started with '-'.
However, for the largest permitted negative fixnum you'll have,
in the last step, a positive number that's just beyond the range
for fixnums, so it is represented as a bignum.  The negation step
just flips the sign bit, without checking if the negated value now
should be a fixnum.

I haven't looked at the list_to_integer case yet, but suspect it's
similar.

/Mikael

 > 
 > Thanks for the bug report!
 > 
 > Lukas
 > On 18/08/14 14:36, Jesper Louis Andersen wrote:
 > > Hi,
 > >
 > > While working on transit-erlang, Isaiah Peng and I found what we 
 > > believe to be a bug in the Erlang compiler:
 > >
 > > 9> A = -576460752303423488.
 > > -576460752303423488
 > > 10> B = binary_to_integer(integer_to_binary(A)).
 > > -576460752303423488
 > > 11> A == B.
 > > false
 > > 12> A.
 > > -576460752303423488
 > > 13> B.
 > > -576460752303423488
 > > 14>
 > >
 > > I expected command 11 (A == B) to return true, as the numbers are the 
 > > same. But it looks like constants are not treated the same way as 
 > > converted vaues for some reason and the equality test fails.
 > >
 > > This fails in the interpreter and in compiled code. It *also* fails 
 > > with list_to_integer/1 and integer_to_list/1.  The number is not 
 > > chosen arbitrarily. It is -1 * 2^59 which is a borderline number on a 
 > > 64bit machine. (OTP release 17.1). Isaiah notes that these borderline 
 > > numbers are not caught by the OTP test cases. They probably should be.
 > >
 > > In the interest of full exploration, I've written a QuickCheck test 
 > > case to catch the remaining trouble. It explicitly tests the 
 > > borderline numbers and only finds this error.
 > >
 > > https://gist.github.com/jlouis/52b68d9d4150af3bd00c
 > >
 > > -module(integer_coding).
 > >
 > > -compile(export_all).
 > >
 > > -include_lib("eqc/include/eqc.hrl").
 > >
 > > power(_N, 0) -> 1;
 > > power(N, P) -> N * power(N, P-1).
 > >
 > > perturb() ->
 > >      elements([0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5]).
 > >
 > > sign() ->
 > >      elements([1, -1]).
 > >
 > > nat_power() ->
 > >      frequency([{1, elements([27, 28, 29, 31, 32, 33, 59, 60, 61, 63, 64, 65])},
 > >                 {1, nat()}]).
 > >
 > > interesting_int() ->
 > >      ?LET({K, Sign, Perturb}, {nat_power(), sign(), perturb()},
 > >        power(2, K)*Sign + Perturb).
 > >
 > > prop_binary_iso() ->
 > >      ?FORALL(K, interesting_int(),
 > >              begin
 > >                  I = binary_to_integer(integer_to_binary(K)),
 > >                  I == K
 > >              end).
 > >
 > > prop_list_iso() ->
 > >      ?FORALL(K, interesting_int(),
 > >              begin
 > >                  I = list_to_integer(integer_to_list(K)),
 > >                  I == K
 > >              end).
 > >
 > > all() ->
 > >      eqc:module({numtests, 3000}, ?MODULE).
 > >
 > > t() ->
 > >      eqc:quickcheck(eqc:testing_time(300, prop_binary_iso())).
 > >
 > >
 > > [...]
 > >
 > > Produces:
 > >
 > > 8> integer_coding:all().
 > > prop_list_iso: ............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
 ..............................................................................................................................................................................................
 ...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................Failed! After 1498 tests.
 > > -576460752303423488
 > > prop_binary_iso: ...........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................Failed! After 588 tests.
 > > -576460752303423488
 > > [prop_list_iso,prop_binary_iso]
 > > 9>
 > >
 > > -- 
 > > J.
 > >
 > >
 > > _______________________________________________
 > > erlang-bugs mailing list
 > > [email protected]
 > > http://erlang.org/mailman/listinfo/erlang-bugs
 > 
 > 
 > ----------------------------------------------------------------------
 > _______________________________________________
 > erlang-bugs mailing list
 > [email protected]
 > http://erlang.org/mailman/listinfo/erlang-bugs

-- 
_______________________________________________
erlang-bugs mailing list
[email protected]
http://erlang.org/mailman/listinfo/erlang-bugs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.