[erlang-bugs] Problem with binary_to_integer/1 and list_to_integer/1 (QuickCheck test case)

Mikael Pettersson mikpelinux@REDACTED
Tue Aug 19 11:30:40 CEST 2014


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
 > > erlang-bugs@REDACTED
 > > http://erlang.org/mailman/listinfo/erlang-bugs
 > 
 > 
 > ----------------------------------------------------------------------
 > _______________________________________________
 > erlang-bugs mailing list
 > erlang-bugs@REDACTED
 > http://erlang.org/mailman/listinfo/erlang-bugs

-- 


More information about the erlang-bugs mailing list