Age | Commit message (Collapse) | Author |
|
|
|
Fix rounding bug in float_to_list/2
|
|
|
|
Example symptom:
1> float_to_list(0.145, [{decimals,1}]).
"0.2"
There were two problems in sys_double_to_chars_fast
1. Most serious was adding 0.55555555 / (10^D) instead of 0.5 / (10^D)
which imposed a 5.5% risk of a faulty rounding up.
2. Using fixpoint for frac_part which lost significant bits if F < 0.5
|
|
Before:
1> binary_to_integer(<<":">>, 16).
3
After:
1> binary_to_integer(<<":">>, 16).
** exception error: bad argument
in function binary_to_integer/2
called as binary_to_integer(<<":">>,16)
Prior to this change, both list_to_integer/2 and binary_to_integer/2
would convert strings with values between ASCII '9' up to '0'+base for
base > 10. For example, when converting in base 16, you could pass ':',
';', '<', '=', '>', and '?' without getting an exception. This was due
to a missing check in c2int_is_invalid_char().
This change adds the missing check and a regression test for passing
':'. It also simplifies the code and tightens up an out-of-bounds check
to make it off-by-one rather than off-by-two.
|
|
|
|
|
|
|
|
1> round(6209607916799025.0).
6209607916799026
Problem: Adding/subtracting 0.5 and large double floats between
(1 bsl 52) and (1 bsl 53) does not give reliable results.
Solution: Use round() function in math.h.
|
|
|
|
Implement as ceil/1 and floor/1 as new guard BIFs (essentially part of
Erlang language). They are guard BIFs because trunc/1 is a guard
BIF. It would be strange to have trunc/1 as a part of the language, but
not ceil/1 and floor/1.
|
|
|
|
As a first step to removing the test_server application as
as its own separate application, change the inclusion of
test_server.hrl to an inclusion of ct.hrl and remove the
inclusion of test_server_line.hrl.
|
|
Now tries to use whole width of signed long (Sint) and this halves amount of
multiplications needed to parse long integers. New code is 2-3 times faster
than the old code for large inputs (tens and hundreds of digits), behavior
should not change for small inputs.
Test ran 10k times with GC forced between attempts.
Was (R17):
720 el base 10: 0.14682 sec; base 16: 0.192722 sec; base 36: 0.337118 sec.
2800 el base 10: 1.794133 sec; base 16: 2.735106 sec; base 36: 4.761108 sec.
6500 el base 10: 9.316434 sec; base 16: 14.109469 sec; base 36: 25.319263 sec.
Now (R19 Dev)
720 el base 10: 0.10265 sec; base 16: 0.10851 sec; base 36: 0.160478 sec.
2800 el base 10: 1.002793 sec; base 16: 1.360649 sec; base 36: 2.174309 sec.
6500 el base 10: 4.722197 sec; base 16: 6.60522 sec; base 36: 10.552795 sec.
Added test for corner cases and sign bit corruption. Replaced macros with
inline and hid it inside C file to not pollute global namespace
Old bug in #define LG2_LOOKUP: Replaced with inline function and table
recalculated for all bases 2 to 36 (was 2 to 64)
|
|
erlang:binary_to_integer/1 and /2 fail to detect invalid
input consisting of a single + or - sign but nothing else.
For an input like <<"+">> they return 0, while list_to_integer/1
correctly signals a badarg for "+".
Fixed by checking if the input is empty after the initial +/-
sign processing.
Added a test case which fails without this fix but passes with it.
Thanks to "niku" for reporting the issue.
|
|
|
|
list_to_integer(lists:duplicate(10000000,$0)).
crashed due to overflow when calculating nr heap words.
|
|
list_to_integer and binary_to_integer returned un-normalized bignum for
-134217728 on 32-bit and -576460752303423488 on 64-bit.
Thanks to Jesper Louis Andersen, Mikael Pettersson
and Anthony Ramine for report, initial patch and optimization suggestion.
|
|
When integer_to_binary/2 receives 0 or a negative number as an argument
with a base that is different from 10, it will return incorrect values
(<<>> in the case of 0) or it will crash (with negative numbers). This
commit fixes these problems and adds tests to cover these cases.
|
|
|
|
Added: binary_to_integer/1,2, integer_to_binary/1,2
|
|
Changed rouding to round half-way up instead of down.
Cosmetic cleanup and error handling of additional edge cases.
|
|
|
|
This BIF solves a problem of float_to_list/1 that doesn't allow
specifying the number of digits after the decimal point when
formatting floats.
float_to_list(Float, Options) -> string()
Float = float()
Options = [Option]
Option = {decimals, Decimals::0..249} |
{scientific, Decimals::0..249} |
compact
Returns a string which corresponds to the text representation of
a `Float` formatted using given options.
When decimals option is specified the returned value will contain
at most `Decimals` number of digits past the decimal point.
When `compact` option is provided the trailing zeros at the end
of the list are truncated (this option is only meaningful together
with the `decimals` option). When `scientific` option is provided,
the float will be formatted using scientific notation with
`Decimals` digits of precision. If `Options` is `[]` the function
behaves like `float_to_list/1`. When using `decimals` option and
the number doesn't fit in the static internal buffer of 256 bytes
the function throws `badarg`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|