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?
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.
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With