[erlang-questions] Strange float / tuple problem

zxq9 zxq9@REDACTED
Sun Jun 5 06:11:30 CEST 2016


On 2016年6月4日 土曜日 10:07:11 Donald Steven wrote:
> Thanks Matthias and Craig.  I see the issue and I've got a work around.  
> BTW, is there a way to truncate a float to a given # of places, not just 
> 0 -- not just a formatted output, but a true truncation?

Keep in mind that in this case you don't want mere truncation -- what
if your teeny, tiny value winds up being teeny, tiny on the negative
side of zero?

You need a test to check for whether a value is "close enough" to a
given value to be considered a valid approximation of it for your case,
and have a way to declare how close "close enough" means. That's not
truncation.

You want to compare to 5.0, for example.
If 5.0000000000001 is close enough then 4.9999999999999 is also.

Unfortunately floats are just hard to deal with (in every language),
but at least floats have strictly defined rules that limit how hard
they are.

The first thing to consider is whether you should really be doing
fixed-point math, or if floats are good enough for your use. Assuming
floats really are a good fit, something like this could help:

approximate(Precision) ->
    fun(Z, Z) -> true;
       (Z, Q) -> (Z - Precision =< Q) and (Q =< Z + Precision)
    end.

1> Approx = numbers:approximate(0.00001).
#Fun<numbers.0.78713399>
2> Approx(1, 2).
false
3> Approx(5, 5).
true
4> Approx(-5.2, -5.2).
true
5> Approx(10, 10.0000000001).
true
6> Approx(10, 10.1).
false
7> Approx(0.0, 4.440892098500626e-16).
true
8> Approx(0.0, -4.440892098500626e-16).
true

This is probably an inefficient implementation -- I've not taken the
time to really examine it carefully, but it should be a pretty clear
what the intent is. You provide a value that represents how close a
value must be to be considered approximately equal and you get back
a function that will check if the input values are that close.

(There are probably some float corner cases that can pop up here, and
its probably more efficient to define precision as a Power base X and
slide things around to compare ranges, etc. but the implementation
isn't the point and I have no idea how any of that would actually hit
the underlying machine without writing it in assembler, so clarity
wins in the majority case.)

Surely there is some library out there that already provides something
like this.

-Craig



More information about the erlang-questions mailing list