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

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Mon Aug 18 14:36:01 CEST 2014


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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20140818/40c7ed46/attachment.htm>


More information about the erlang-bugs mailing list