float_to_list(X)

Thomas Depierre depierre.thomas@REDACTED
Sun May 9 08:23:17 CEST 2021


Small point: float_to_list/2 will get it soon, (OTP25 at most) and i hope
we can make it the default in float_to_list/1.

Something worth pointing out, a lot of these shortest roundtrip without
loss of precision are slightly broken. The main reason it is not present in
most language is that glibc printf cannot do it (no %g is not the same) and
that until fairly recently (2018) it was not known how to make it fast and
not need Big Integers.

On Sun, 9 May 2021 at 02:05, Bob Ippolito <bob@REDACTED> wrote:

> Modern JavaScript does have BigInt. No syntax support though, so it is not
> very ergonomic.
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
>
> Many (most?) modern float-to-string functions will use the minimal number
> of digits that can represent the float exactly (round-trip without loss of
> precision). Erlang's float_to_list/1 is a relic that does not, possibly for
> backwards compatibility reasons. I bet changing it would at least break
> some brittle tests :) Fortunately the functionality is available in OTP
> these days, in a roundabout way.
>
>
> On Sat, May 8, 2021 at 3:37 PM Peer Stritzinger <peer@REDACTED>
> wrote:
>
>> Just reading that you come from a accounting background: this messiness I
>> described is the reason its a quite bad idea to represent monetary values
>> as floats because its also the reason that:
>>
>> This is not exactly what was requested by the current tutorial step. Feel
>> free to play with the shell, anyway.
>>
>> > 0.1 + 0.1 + 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1+ 0.1.
>> 0.9999999999999999
>>
>> No Erlangs floating point implementation isn’t broken (at least not in
>> this way).  All floating point implementation based on binary fractions
>> behave like this.
>>
>> Thats why some languages used for finance have decimal fractions and in
>> languages that don’t the only sane way to represent monetary values are
>> using a integer multiple of some fixed fraction of the currency involved
>> (like pico euro).  Its nice if you have a non overflowing integer
>> representation like in Erlang for that BTW.
>>
>> Now imagine JavaScript has no integers but only floats (if they just
>> added integers recently I take that back partially ;-) and are used to
>> represent money quite a bit -> joy!
>>
>> Cheers,
>> -- Peer
>>
>>
>> > On 9. May 2021, at 00:27, Peer Stritzinger <peer@REDACTED>
>> wrote:
>> >
>> > I think for the sake of the OP "round trip" needs explaining:
>> >
>> > It does not mean that “arbitrary float string X” -> float -> “string
>> identical to X” is true.
>> >
>> > It does however mean: float Y -> string representation -> float Y.
>> >
>> > One problem is that many fractions like e.g. the simple example of
>> decimal 0.1 are representable as a finite binary fraction:
>> >
>> > 0.1 base 10 is 0.00011001100110011… base 2 (where … means its a
>> infinite repetition of the digits 0011)
>> >
>> > So converting seemingly harmless base 10 floating point strings result
>> in infinite binary fractions.  Then it depends on how they are rounded if
>> conversion back to base 10 string gives you the same string or a rounding
>> error shows.
>> >
>> > Cheers,
>> > -- Peer
>> >
>> >> On 7. May 2021, at 13:57, Thomas Depierre <depierre.thomas@REDACTED>
>> wrote:
>> >>
>> >> That is not true.
>> >>
>> >> The formatting used in format ~p is the shortest round trip one. This
>> will be different for every single binary floating point number but also be
>> far shorter and readable. There is work in progress to bring this as an
>> option in float_to_list/2 thanks to the recent work in Ryu and Dragonbox.
>> >>
>> >> Having a fixed precision already exist in float_to_list/2. This works
>> as printf %f. I strongly advise to not use it as this precision does not
>> translate well to the binary format precision loss.
>> >>
>> >> I understand that float to string and string to float conversion are
>> thought as niche topic, so i will be happy to provide all the bibliography
>> you may need to explore it if you are surprised by my explanations.
>> >>
>> >> Kindly,
>> >>
>> >> Thomas Depierre
>> >>
>> >>
>> >> On Fri, 7 May 2021, 12:27 Richard O'Keefe, <raoknz@REDACTED> wrote:
>> >> No, making float_to_list/1 a wrapper for format... does not make sense.
>> >> float_to_list/1 is meant to give you an accurate representation of the
>> >> value.  Two different floats, no matter how small the difference,
>> >> should result in different lists.  It's meant for converting a float
>> >> to text that you can send to another machine and reconstitute the
>> >> same value there.  This will usually result in more digits than a human
>> >> would normally want to see.
>> >>
>> >> If you *want* format ~p, use it!
>> >>
>> >> Now perhaps there might be an argument to be made for
>> >> float_to_list(X: number(), N: integer()) -> string()
>> >> returning a string that represents X as accurately as
>> >> possible using N digits.  But that is another discussion.
>> >>
>> >> On Thu, 6 May 2021 at 20:56, Themba Jonga <themba.jonga@REDACTED>
>> wrote:
>> >> Hi, again.
>> >>
>> >> Following a response I got from Dmitry Klionsky, perhaps it makes
>> sense for float_to_list(N) to be made into a wrapper for
>> lists:flatten(io_lib:format("~p",[N]))?
>> >>
>> >> Eshell V11.1  (abort with ^G)
>> >> 1> N = 4.4445.
>> >> 4.4445
>> >> 2> lists:flatten(io_lib:format("~p",[N])).
>> >> "4.4445"
>> >> 3> P = 5.4443.
>> >> 5.4443
>> >> 4> lists:flatten(io_lib:format("~p",[P])).
>> >> "5.4443"
>> >> 5> Q = 1.2345678.
>> >> 1.2345678
>> >> 6> lists:flatten(io_lib:format("~p",[Q])).
>> >> "1.2345678"
>> >> 7> float_to_list(Q).
>> >> "1.23456779999999999298e+00"
>> >> 8>
>> >>
>> >> Regards
>> >>
>> >> Themba Jonga
>> >>
>> >>
>> >>
>> >>      Virus-free. www.avg.com
>> >>
>> >> On Wed, 5 May 2021 at 18:38, Scott Ribe <scott_ribe@REDACTED>
>> wrote:
>> >> > On May 5, 2021, at 10:20 AM, 2QdxY4RzWzUUiLuE@REDACTED
>> wrote:
>> >> >
>> >> > In short, no.
>> >>
>> >> Although many (most, actually nearly all) real numbers cannot be
>> represented precisely as a float, any float can be round-tripped to text
>> and back exactly. This is part of the IEEE floating point standard,
>> actually. (And it's not easy...)
>> >>
>> >>
>> >>
>> >>      Virus-free. www.avg.com
>> >
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20210509/f4964882/attachment.htm>


More information about the erlang-questions mailing list