The previous implementations for ceil, floor and round were
not formalized and were likely prone to multiple roundings
as we performed multiplication and division by a power of
10 on the given float.
The new implementation correctly converts the float to an
exact integer representation and perform all operations using
arbitrary precision integers. The only float operation occurs
when converting the ratio back to a float.
The current implementation is more expensive due to its reliance
on big integers. Faster implementations are available in literature
where the latest one seems to be Errol:
https://cseweb.ucsd.edu/~lerner/papers/fp-printing-popl16.pdf
This change also introduces Float.ratio/1 which receives a
float and returns a pair of integers whose ratio is exactly equal
to the original float and with a positive denominator.
Closes#3400
Prior to this change, calling a protocol function with an opaque type
would yield a warning, as Dialyzer concludes that the impl_for/1
function can't handle opaque arguments, since all clauses would
destructure their arguments in some way.
By adding a catch-all clause that does not destructure its argument,
Dialyzer no longer draws this conclusion, and the warnings go away.
As noted in the protocol.ex comment, this is technically a hack as it
relies on Dialyzer not being smart enough. However, I would not expect
it to break soon, if ever.
The previous format would use | before code blocks
and would remove # from headings, we have reverted
those changes to make the printed documentation and
help be closer to what it would look on source while
providing more information (in the case of headings).
Right now, application of anonymous function literals in
Macro.to_string/2 is represented like this:
iex> Macro.to_string(quote do: (fn x -> x end).(1))
"fn x -> x end.(1)"
While this is valid, I think it's far more common to have such calls
with the literal fn wrapped in parens:
(fn x -> x end).(1)
This commit makes Macro.to_string/2 behave like this.
Right now, Kernel.macro_exported?/3 blindly calls __info__/1 on the
given module, but since __info__/1 is defined by Elixir when compiling
modules, this breaks if an Erlang module is passed to
macro_exported?/3. This commit fixes this behaviour by always returning
"false" in macro_exported?/3 when an Erlang module is given.
Change how we mark the generated AST for suppressing dialyzer errors -
instead of [generated: true, location: 0], we provide proper line number.
This means, however, that on OTP 18, those nodes won't be recognized
as generated and warnings will be issued.
It was decided that proper error messages are more important than
avoiding bogus dialyzer warnings.
The old mark for generated code is left in places that made compiler
issue warnings on 18.
The bad remote call dialyzer warnings can be suppressed with the
@dialyzer :no_fail_call
module attribute.