[erlang-patches] new float_to_list/2

Serge Aleynikov <>
Fri Jan 11 04:06:47 CET 2013


I implemented Lukas's recommendations that were presenting an acceptance
issue of the new function, so the current version of the patch does:

1. float_to_list/1 is backwards compatible.
2. float_to_list(X,[]) gives the same result as float_to_list(X).
3. float_to_list(X,[{decimals,N}]) uses the new fast implementation
(with the optional compact option).
4. float_to_list(X,[{scientific,M}]) gives the same result as
float_to_list(X) with the ability to control the number of decimals.

The only item from Lucas's list that I left unchanged was the
modification to erts/lib_src/common/erl_printf_format.c to take
advantage of the speed improvement of the new implementation.  I am
including a patch in this email that implements this logic, but I
decided to leave the integration task to the OTP team since
erl_printf_format.c is actually compiled into a liberts_internal.a
library and I didn't want to introduce a dependency of it on other code
- this should be decided by maintainers.

The test cases of float_to_list/{1,2} have been updated.

git fetch https://github.com/saleyn/otp/tree/float_to_list_2

https://github.com/saleyn/otp/compare/maint...float_to_list_2
https://github.com/saleyn/otp/compare/maint...float_to_list_2.patch

Regards,

Serge

On 8/23/2012 5:10 AM, Lukas Larsson wrote:
> Hi,
> 
> I'll put it in the backlog and we'll see if it gets prioritized for R16B.
> 
> As always if you (or someone else) wants make sure it gets in, the best
> way to ensure that is to send an updated patch.
> 
> Lukas
> 
> 
> On 22/08/12 21:17, Serge Aleynikov wrote:
>> I am certainly very happy to hear that you finally agreed to include
>> this in the distribution.  The changes proposed below seem reasonable
>> and simple.  Will the OTP team be able to modify my patch to implement
>> them?
>>
>> On 8/22/2012 12:01 PM, Lukas Larsson wrote:
>>> Hello Serge!
>>>
>>> I think we have finally agreed how we want this functionality to work.
>>>
>>> float_to_list/1 should be left as it is now for backwards compatibility.
>>> float_to_list(1.0,[]) should give the same as float_to_list(1.0).
>>> float_to_list(1.0,[{decimals,X}]) should use your faster implementation
>>> (with the optional compact option).
>>> float_to_list(1.0,[{scientific,Y}]) should give the same as
>>> float_to_list(1.0) if Y is 20.
>>>
>>> We would also like the string rendering part of sys_double_to_chars_fast
>>> to be put into erts/lib_src/common/erl_printf_format.c:fmt_double. This
>>> way other parts of the vm which print floats will benefit from your
>>> changes!
>>>
>>> I hope our indecisiveness have not caused you to shy away from taking
>>> this feature into Erlang/OTP. If you have any further questions or
>>> ponderings just let me know.
>>>
>>> Lukas
>>>
>>> On 18/07/12 20:47, Serge Aleynikov wrote:
>>>> On 7/18/2012 5:18 AM, Lukas Larsson wrote:
>>>>> However, I would also like the fast functionality to be used by
>>>>> float_to_list_1 as well, is possible to do this and stay backwards
>>>>> compatible? Hopefully you just have to shift the comma and add e+XX at
>>>>> the end of the optimized case and call sys_double_to_chars for the
>>>>> unoptimized.
>>>> See my comments below regarding 'scientific' option.  Since
>>>> float_to_list_2 is a new function I would think that you are
>>>> questioning
>>>> the issue of backward compatibility only in terms of converting
>>>> float_to_list_1 to use float_to_list_2 implementation.  However, I
>>>> think
>>>> that this will have adverse performance tax on float_to_list_2, which
>>>> will diminish the benefit.  It's been a while however, since I wrote
>>>> that patch, perhaps there's a way to retrofit scientific notation
>>>> without a performance penalty.
>>>>
>>>> It's more than simple shifting of the comma, since there's also
>>>> rounding
>>>> involved.
>>>>
>>>> This case is easy:
>>>>
>>>> 4> float_to_list(1.01234).
>>>> "1.01234000000000001762e+00"
>>>> 5> float_to_list(1.01234, [{decimals, 20}]).
>>>> "1.01234000000000001762"
>>>>
>>>> This case is a bit more complex (illustration of rounding impact):
>>>>
>>>> 7> float_to_list(10123412345.0123451234).
>>>> "1.01234123450123443604e+10"
>>>> 8> float_to_list(10123412345.0123451234, [{decimals, 20}]).
>>>> "10123412345.01234436035156250000"
>>>>
>>>>> Also float_to_list(1.0) should return the same thing as
>>>>> float_to_list(1.0,[]), otherwise the API will be inconsistent with how
>>>>> other such APIs work.
>>>> Actually if you trace this subject back there was another request that
>>>> the default number of decimals is chosen to be consistent with what
>>>> printf() does, so I changed the implementation to accommodate that
>>>> request:
>>>>
>>>> Eshell V5.9  (abort with ^G)
>>>> 1> float_to_list(1.0, []).
>>>> "1.000000"
>>>>
>>>> Which is different from the default of float_to_list/1:
>>>>
>>>> 2> float_to_list(1.0).
>>>> "1.00000000000000000000e+00"
>>>>
>>>> Maybe one could introduce a 'scientific' option to float_to_list/2, to
>>>> use the float_to_list/1 implementation?
>>>>
>>>> Serge
>>>>
>>>>> On 24/05/12 16:02, Serge Aleynikov wrote:
>>>>>> Henrik,
>>>>>>
>>>>>> Fetch:    git fetch
>>>>>> https://github.com/saleyn/otp/tree/float_to_list_2
>>>>>> Diff:    https://github.com/saleyn/otp/compare/float_to_list_2
>>>>>>
>>>>>> I added the definition for the new BIF to make the type checker
>>>>>> happy:
>>>>>> https://github.com/saleyn/otp/commit/f9ddbeda5426ca83cda03c06a9860220ea4a22c7
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Once you do the "otp_build tests", how do you execute all tests
>>>>>> suites
>>>>>> in $ERL_TOP or if possible only tests in a given SUITE?  I tried the
>>>>>> following but all tests fail:
>>>>>>
>>>>>> [otp/erts/emulator/test]$ ../../../bin/erl -noshell -s
>>>>>> test_server_ctrl
>>>>>> run_test DIR "." -s erlang halt
>>>>>>
>>>>>> I did however run individual tests in bif_SUIT:types to make sure my
>>>>>> patch didn't break anything.
>>>>>>
>>>>>>
>>>>>>
>>>>>> Serge
>>>>>>
>>>>>> On 5/24/2012 5:17 AM, Henrik Nord wrote:
>>>>>>> Hi again.
>>>>>>>
>>>>>>>
>>>>>>> This test is not passing: emulator/bif_SUIT:types
>>>>>>>
>>>>>>> No type information:
>>>>>>>
>>>>>>> [{erlang,float_to_list,2}]
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 04/21/2012 07:19 AM, Serge Aleynikov wrote:
>>>>>>>> git fetch https://github.com/saleyn/otp/tree/float_to_list_2
>>>>>> _______________________________________________
>>>>>> erlang-patches mailing list
>>>>>> 
>>>>>> http://erlang.org/mailman/listinfo/erlang-patches
>>>>>>
>>>> _______________________________________________
>>>> erlang-patches mailing list
>>>> 
>>>> http://erlang.org/mailman/listinfo/erlang-patches
>>>>
>> _______________________________________________
>> erlang-patches mailing list
>> 
>> http://erlang.org/mailman/listinfo/erlang-patches
>>
> 
-------------- next part --------------
--- erts/lib_src/common/erl_printf_format.c	2013-01-10 20:28:02.865909745 -0500
+++ erts/lib_src/common/erl_printf_format.c.new	2013-01-10 20:27:41.987369169 -0500
@@ -383,7 +383,7 @@
 	}
 	/* fall through ... */
     case FMTC_f:
-	format_str[fi++] = 'f';
+	/* format_str[fi++] = 'f'; */
 	max_size += exp > 0 ? exp : 1;
 	max_size++;
 	if (precision)
@@ -435,6 +435,9 @@
 	}
     }
 
+    if ((fmt & FMTC_MASK) == FMTC_f)
+        size = sys_double_to_chars_fast(val, bufp, max_size, precision, 0);
+    else
     size = sprintf(bufp, format_str, precision, val);
     if (size < 0) {
 	if (errno > 0)


More information about the erlang-patches mailing list