[erlang-questions] OtpErlangDouble/OtpErlangFloat

Martin Dimitrov mrtndimitrov@REDACTED
Thu Aug 9 15:12:12 CEST 2012


Thanks for the explanation. I know it is not Erlang to be blamed.


On 8/9/2012 1:41 AM, Richard O'Keefe wrote:
> On 8/08/2012, at 11:01 PM, Martin Dimitrov wrote:
>
>> Hello,
>>
>> I have some strings in Java representing floating point numbers. I want
>> to transfer them to Erlang. So I create an object of type
>> OtpErlangFloat. The problem is that is rounds the number funnily. For
>> example,
>>
>> String s = "22.4";
>> float f = Float.parseFloat(s);
> Here you asked for a SINGLE-PRECISION floating point number.
> I presume you did try
>
> Prelude> 22.4 - 22.399999618530273
> 3.8146972514141453e-7
>
> and you did notice that the difference is about the size of
> single precision epsilon?
> Well that's why.  You asked for a number with 24 bits of
> precision that was close to 22.4, and 22.399999618530273
> was indeed the answer you got.
>
>> System.out.println(f); // 22.4
> PrintStream.println(float) calls
> PrintStream.print(float) calls
> String.valueOf(float) calls
> Float.toString(float) 
>
> whose documentation says (for this value of m) tha
> it will be the integer part, then a dot, then "as
> any, but only as many, more digits as are needed to
> uniquely distinguish the argument value from adjacent
> values of type 'float'".
>
> So the value that is printed is the _least_ precise
> decimal representation that cannot be mistaken for
> a different single-precision (24 bits of precision)
> float.
>
> If you convert the same value to a double in Java and
> print that in Java, you will get, well, try it:
>
> L% cat NotErlangsFault.java
> public class NotErlangsFault {
>     public static void main(String[] args) {
>         final String    s = "22.4";
>         final float     f = Float.parseFloat(s);
>         final double    d = (double)f;
>
>         System.out.println(s + " converts to float " + f +
>             " which as double is " + d);
>     }
> }
>
> L% java NotErlangsFault
> 22.4 converts to float 22.4 which as double is 22.399999618530273
>
> See?   Nothing to do with Erlang at all.
>
>> OtpErlangFloat ef = new OtpErlangFloat(f);
>> System.out.println(ef.toString()); // 22.399999618530273
> And this tells us that an OtpErlangFloat contains a Java double,
> which is *more* precise than the float you gave it.
>> Then in Erlang:
>>
>> mochinum:digits(Ef).
>> "22.399999618530273"
> And this is the right answer.
>> but
>>
>> mochinum:digits(22.4).
>> "22.4"
>>
>> Is there a way to keep the precision when constructing
>> OtpErlangDouble/OtpErlangFloat?
> No precision whatsoever was lost in that step.
>
> The precision was lost when you first converted a String
> to a float.  The value in the float really *is* much
> better approximated by 22.399999618530273 than by 22.4.
>





More information about the erlang-questions mailing list