[erlang-questions] erlang float comparison

Angel J. Alvarez Miguel <>
Tue May 15 11:04:40 CEST 2012


Hi Guys

Thanks for all the comments and all those details. after reading the articles, 
that Richard pointed out, and think a bit about what we need i endended with two 
solutions that for the most part allow us to get it fixed for the moment:

The problem can be stated as:

Result = case Myfloat > 1.0 of
	true -> 1.0;
	false MyFloat
	end
...
...
math:acos(Result).

after that  we came across some values that fail to pass the test > 1.0 but are seen 
as greater to the math:acos function rendering a bad arithmetic expression error so finally we manage to do

Result  = case trunc(MyFloat) < 1 of
	true -> MyFloat;
	false -> 1.0
	end

...
...
math:acos(Result).

that unless anyone see some hidden mosnter that will bite us the... i think it solves our problem.


"...My 1st-year chemistry days are long past, but web pages I've checked
today seem not to quote any bond angles to better than 1 part in 1000
precision.  And since angles are constrained to [0,one circle), it
looks to me very much as if we have a case for representing bond angles
and dihedral angles as fixed point numbers, or at any rate for
rounding them to multiples of say (one circle)/65536 and comparing
the angles as integers."

Well take a look at this approach, math code is almost finished as my cooworker ported it from
an earlier python tool he had developed wher he managed to fix this in a diferent fashion.
So i was working on the OTP part while we found this "feature" but provided that we have enough 
time to check and surely we will refactor some code to be carried ogen_fsm,'s maybe...



/Angel 

On Lunes, 14 de Mayo de 2012 09:41:01 Angel J. Alvarez Miguel escribió:
> 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

-- 
-



More information about the erlang-questions mailing list