[erlang-questions] erlang float comparison

Hynek Vychodil <>
Mon May 14 11:18:36 CEST 2012


They are exactly same numbers:

1> <<1.000000000000000002/float>>.
<<63,240,0,0,0,0,0,0>>
2> <<1.0/float>>.
<<63,240,0,0,0,0,0,0>>
3> 1.000000000000000002.
1.0

Anyway I think I know what you are about. You want work with numbers
in some interval as they are same. Something like

1> F = fun(X) when is_float(X) -> <<V:32, _/binary>> = <<X/float>>,
<<F/float>> = <<V:32, 0:32>>, <<T/float>> = <<V:32, 16#ffffffff:32>>,
{F, T} end.
#Fun<erl_eval.6.82930912>
2> F(1.0).
{1.0,1.0000009536743162}
3> F(0.99999999).
{0.9999995231628418,0.9999999999999999}
4> F(1.99999976).
{1.9999990463256836,1.9999999999999998}

So you would be able make approximate comparison:

5> Comp = fun(X, Y, N) when is_float(X), is_float(Y), is_integer(N),
N>16, N<64 -> <<XI:N,_/bits>> = <<X/float>>, <<YI:N,_/bits>> =
<<Y/float>>, if XI < YI -> lt; XI =:= YI -> eq; XI > YI -> gt end end.
#Fun<erl_eval.18.82930912>
6> Comp(1.99999976, 1.99999988, 32).

                                                      eq
7> Comp(1.99999976, 1.99999988, 48).

                                                      lt
lt

On Mon, May 14, 2012 at 10:47 AM, Angel J. Alvarez Miguel <> wrote:
> Well we just picked the wrong example
>
>
> that's is the problem
>
> :~> erl
> Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:4:4] [async-threads:0]
> [hipe] [kernel-poll:false]
>
> [QuickCheck] [PropEr] [Erl0MQ]
> Eshell V5.9.1  (abort with ^G)
> 1> 1.000000000000000002 > 1.0.
> false
>
>
> On Lunes, 14 de Mayo de 2012 09:50:57 usted escribió:
>> 1> 0.99999998 < 1.000000.
>> true
>> 2> 1.99999976 < 1.99999988.
>> true
>>
>> What's the problem?
>>
>> On Mon, May 14, 2012 at 9:41 AM, Angel J. Alvarez Miguel
> <>wrote:
>> > **
>> >
>> >
>> > Hi guys
>> >
>> >
>> >
>> > I need to compare two floats something like 0.99999998... vs 1.000000
>> >
>> > and we came across accuracy problems when testing dihedral angles on a
>> > molecule...
>> >
>> >
>> >
>> > so we read
>> > http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
>> >
>> > and wanted to implement something like:
>> >
>> >
>> >
>> > if (*(int*)&f1 < *(int*)&f2)...
>> >
>> >
>> >
>> > when ef1 and f2 are floats... (f1 about 0.9999899.. and f2=1.0
>> >
>> >
>> >
>> > is think we should start with...
>> >
>> >  <<Padding:16,Myint:64>> = term_to_binary(1.9999976,[{minor_version,1}]).
>> >
>> > and let Padding swallow the external format and tag while Myint gets the
>> > ieee754 float
>> >
>> >
>> >
>> > But MyInt = 4611686017346523993 instead of 1073741822
>> >
>> > these conversion should follow ieee754 and being lexicografic ordered
>> >
>> > but ...
>> >
>> > term_to_binary(1.99999976,[{minor_version,1}]).
>> >
>> > <<131,70,63,255,255,255,191,147,83,89>>
>> >
>> > term_to_binary(1.99999988,[{minor_version,1}]).
>> >
>> > <<131,70,63,255,255,255,223,201,169,173>>
>> >
>> > doesnt seem to be the same thatn you spect to see after reading that
>> > page...
>> >
>> >  ..What im doing wrong....?
>> >
>> > ieee754 layout....
>> >
>> >   +1.99999976
>> >
>> > 0x3FFFFFFE
>> >
>> > 1073741822
>> >
>> > +1.99999988
>> >
>> > 0x3FFFFFFF
>> >
>> > 1073741823
>> >
>> > +2.00000000
>> >
>> > 0x40000000
>> >
>> > 1073741824
>> >
>> > +2.00000024
>> >
>> > 0x40000001
>> >
>> > 1073741825
>> >
>> > +2.00000048
>> >
>> > 0x40000002
>> >
>> > 1073741826
>> >
>> > Thanks!..
>> >
>> > /Angel
>> >
>> >
>> >
>> >
>> >
>> >
>> > _______________________________________________
>> > erlang-questions mailing list
>> > 
>> > http://erlang.org/mailman/listinfo/erlang-questions



-- 
Hynek Vychodil
Chief Scientists

GoodData
náměstí 28. října 1104/17, 602 00, Brno - Černá Pole
Office:   +420 530 50 7704
E-mail:  
Web:     www.gooddata.com



More information about the erlang-questions mailing list