whats wrong with this syntax
# this works: this is :math.pow(26,26)
61561195802071577546418399337250816|> div(26)
# but this won't
:math.pow(26,26)|> div(26)
# neither this:
6.156119580207158e36|>div(26)
whats wrong with this syntax
# this works: this is :math.pow(26,26)
61561195802071577546418399337250816|> div(26)
# but this won't
:math.pow(26,26)|> div(26)
# neither this:
6.156119580207158e36|>div(26)
div works for integerâ€¦
why not use / ?
iex> :math.pow(26,26)/26
2.367738300079676e35
iex> 6.156119580207158e36/26
2.367738300079676e35
# how to get remainder, I don't see a % operator . For uniformity I thought i will use div and rem functions.
6.156119580207158e36|>rem(26)
iex(8)> :math.pow(26,26) == 61561195802071577546418399337250816
false
:math.pow(26,26)
produces a float not an integer. Div doesnâ€™t work with floats.
You can use trunc/1
to convert a floating point to an integer. trunc converts a float to the closest less than or equal integer value
iex(84)> :math.pow(26, 26) |> trunc |> rem(26)
0
div/2
and rem/2
are only defined for integer inputs because they are fundamentally about integer math
ic! so there no elixir equivalent for a ruby code which looks like this ? (in other words how to find remainders for a float? )
irb(main):007:0> (100 ** 100) % 12345
=> 10030
irb(main):008:0>
The problem is that the result from :math.pow/2
is a float in IEEE 754 format (from a C library) which isnâ€™t precise.
iex(1)> defmodule Test do
...(1)> use Bitwise
...(1)>
...(1)> def pow(_, 0) do
...(1)> 1
...(1)> end
...(1)>
...(1)> def pow(x, 1) do
...(1)> x
...(1)> end
...(1)>
...(1)> def pow(x, y) do
...(1)> z = pow(x, y >>> 1)
...(1)> w = if((y &&& 1) === 0, do: 1, else: x)
...(1)> z * z * w
...(1)> end
...(1)> end
{:module, Test,
<<70, 79, 82, 49, 0, 0, 5, 136, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 133,
0, 0, 0, 16, 11, 69, 108, 105, 120, 105, 114, 46, 84, 101, 115, 116, 8, 95,
95, 105, 110, 102, 111, 95, 95, 7, 99, ...>>, {:pow, 2}}
iex(2)>
nil
iex(3)> Test.pow(100, 100) |> rem(12345)
10030
iex(4)>
Even aside from the specifics of the IEEE floating point number representation, a remainder from dividing a decimal number by another number really doesnâ€™t make mathematical sense. You have a decimal, you divide, you get a decimal back. Remainders only matter when you are dealing in the domain of whole number integers.
Ruby was just hiding that from you by implicitly casting your float to an integer.
thanks, It was a question out of Curiosity on how Elixir deals with extremely larger numbers.
It does not:
3.5 % 3 #=> 0.5
3 % 2.5 #=> 0.5
Neither of its arguments seems to be converted to integer. I get a result that is expected and would hold the usual n = m * d + r
(+/- IEEE inaccuracy).
Sadly it seems as if I am not able to get d
for floats easily in ruby which makes the %
behaviour pretty uselessâ€¦
You should have said so! It transparently uses bignums https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic limited only by available memory
My apology for mis-speaking. I was speaking about the conceptual nature of div and rem only making sense for integers. I honestly have no idea how Ruby implements it.
@gregvaughn, Thank you for the update. Syntax below seems to be one way of solving it.
round(:math.pow(100,100))
Kernel.trunc/1
Rounding towards zero
Kernel.round/1
Rounding half away from zero
https://floating-point-gui.de/errors/rounding/
And :math
functions donâ€™t calculate with bignums - 64-bit IEEE standard floating point results are converted to bignum values locking in the inherent loss in precision.
So
iex(2)> :math.pow(100, 100) |> trunc |> rem(12345)
398
iex(3)> :math.pow(100, 100) |> round |> rem(12345)
398
iex(4)>
is wrong either way.
thanks. So there isnâ€™t any out of the box solution for this in Elixir.(an equivalent syntax from ruby is given below)
2.6.0 :002 > number = 100 ** 100
=> 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2.6.0 :003 > number.divmod(26)
=> [3846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153, 22]
iex(1)> num = [100] |> Stream.cycle |> Enum.take(100) |> Enum.reduce(&(&1*&2))
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
iex(2)> {div, mod} = {div(num, 26), rem(num, 26)}
{3846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153846153,
22}
Not exactly as nice, but easily implementable in a helper functionâ€¦