Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Precision in Erlang

Next code gives me 5.999999999999998 in Result, but right answer is 6.

Alpha = math:acos((4*4 + 5*5 - 3*3) / (2*4*5))
Area = 1/2 * 4 * 5 * math:sin(Alpha)

Is it possible to get 6?

like image 560
Yola Avatar asked Oct 05 '11 14:10

Yola


People also ask

What is precision value in float?

float is a 32-bit IEEE 754 single precision Floating Point Number – 1 bit for the sign, 8 bits for the exponent, and 23* for the value. float has 7 decimal digits of precision.

What is the precision of real numbers?

A single-precision, floating-point number is a 32-bit approximation of a real number. The number can be zero or can range from -3.40282347E+38 to -1.17549435E-38, or from 1.17549435E-38 to 3.40282347E+38. When the precision of a FLOAT is in the range of 1 to 21, the query processor treats the column as REAL.

Which is the precision of float data type?

FLOAT data types usually require 8 bytes of storage per value. Conversion of a FLOAT value to a DECIMAL value results in 17 digits of precision.

What is single precision and double precision?

The Difference Between Single and Double PrecisionFor single precision, 32 bits are used to represent the floating-point number. For double precision, 64 bits are used to represent the floating-point number.


2 Answers

You have run into a problem so common that it has its own web site, What Every Programmer Should Know About Floating-Point Arithmetic. The problem is due to the way floating-point arithmetic works in pretty much every CPU on the market that supports FP arithmetic; it is not specific to Erlang.

If regular floating point arithmetic does not give you the precision or accuracy you need, you can use an arbitrary precision arithmetic library instead of the built-in arithmetic. Perhaps the most well-known such library is GMP, but you'd have to wrap it in NIFs to use it from Erlang.

There is at least one pure-Erlang alternative, but I have no experience with it, so I cannot personally endorse it.

like image 72
Warren Young Avatar answered Sep 16 '22 11:09

Warren Young


The calculation is done using standard floating point arithmetic on your hardware. Sometimes rounding errors show up.

Do you really need 15 digits of precision?

To get a more "exact" value there are multiple options:

> round(Area). % Will round to integer
6

or you could round to some precision

round(Area * 10000000) / 10000000.
6.0

If the purpose is to print the value, then printing with the default output for floats give you less precision.

io:format("~f~n", [Area]).
6.000000
ok

or with a specific precision

io:format("~.14f~n", [Area]).
6.00000000000000
ok

HTH

like image 20
Daniel Luna Avatar answered Sep 20 '22 11:09

Daniel Luna