chunky v0.13.0 Chunky.Fraction View Source
Functions for creating and manipulating fractions.
Most functions will work with combinations of Fractions and Integers. All of the fraction functions work with explicit integer numerators and denominators, falling back to returning floating point number only when configured to in special circumstances.
Value Coercion
A subset of functions for working with fractions will automatically coerce things that
look like fractions - any value that can be parsed by some version of new/1
. This
includes:
- Existing fractions
%Fraction{num: 22, den:7}
- Integers
14
- Floats
1.75
- 2-tuples
{3, 91}
- Integer as String
"4"
- Float as String
"1.35"
- Fraction as String
"2/9"
See new/1
for more information about how values are converted to fractions.
The following functions support mixed types as parameters, either positionally (like the basic math functions) or as part of a list (aggregate functions):
absolute_value/1
add/3
ceiling/1
divide/3
floor/1
multiply/3
subtract/3
gt?/2
gte?/2
lt?/2
lte?/2
eq?/2
clamp/2
fractionalize/1
max_of/1
max_of/2
min_of/1
min_of/2
min_max_of/1
normalize_all/1
power/3
round/1
sort/2
sum/1
uniq/2
within?/2
within?/3
Creating Fractions
Construct fractions from a single integer, tuple of integers, or a pair of integer parameters.
new/1
- Create a Fraction from an integer, float, string, or tuple of integersnew/2
- Create a Fraction from a numerator and denominator, or a float with options
iex> Fraction.new(3)
%Fraction{num: 3, den: 1}
iex> Fraction.new({22, 7})
%Fraction{num: 22, den: 7}
iex> Fraction.new(0.25, conversion: :precision)
%Fraction{num: 1, den: 4}
iex> Fraction.new("-33/913")
%Fraction{num: -33, den: 913}
iex> Fraction.new(5, 11)
%Fraction{num: 5, den: 11}
Basic Math
Standard math functions that work with two fractions, or a fraction and an integer. Options allow for automatic simplification and control over how certain operations work.
absolute_value/1
- Absolute value|v|
of fractionadd/3
- Add two fractions, or a fraction and a value compatible withnew/1
ceiling/1
- Round a fraction up to the nearest whole valuedecrement/2
- Decrement the numerator or denominator by onedivide/3
- Divide two fractions, or a fraction and a value compatible withnew/1
floor/1
- Round a fraction down to the nearest whole valueincrement/2
- Increment the numerator or denominator by onemax_of/2
- Find the larger of two fractions, or a fraction and a value compatible withnew/1
min_of/2
- Find the smaller of two fractions, or a fraction and value compatible withnew/1
multiply/3
- Multiply two fractions, or a fraction and a value compatible withnew/1
power/3
- Take a fraction or an integer to the power of a fraction or an integerround/1
- Round to the nearest whole valuesubtract/3
- Subtract two fractions, or a fraction and a value compatible withnew/1
iex> Fraction.new(4, 3) |> Fraction.add(Fraction.new({1, 6})) |> Fraction.power(2)
%Fraction{num: 81, den: 36}
iex> Fraction.power(8, Fraction.new(1, 3))
%Fraction{num: 2, den: 1}
Comparisons
Binary comparisons between two fractions or a fraction and an integer.
eq?/2
- Equality (==
) comparison between two fractions, or a fraction and an integergt?/2
- Greater than (>
) comparison between two fractions, or a fraction and an integergte?/2
- Greater than or equal (>=
) comparison between two fractions, or a fraction and an integerlt?/2
- Less than (<
) comparison between two fractions, or a fraction and an integerlte?/2
- Less than or equal (<=
) comparison between two fractions, or a fraction and an integernear_equal?/3
- Test if the difference between two fractions is less than or equal to another fractionwithin?/2
- Test if a fraction is within the specified Rangewithin?/3
- Test if a fraction is within the lower and upper value bounds
iex> Fraction.gt?(Fraction.new(7, 8), Fraction.new(8, 9))
false
iex> Fraction.eq?(3, Fraction.new(27, 9))
true
Fraction Manipulation
Manipulate the components of individual fractions.
components/1
- Get the numerator and denominator of a fraction as a tuple of integersget_remainder/1
- Get fractional remainder after removing all whole values of a fractionget_whole/1
- Get whole value portion of a fractionreciprocal/2
- Inverse or reciprocal of a fractionsimplify/1
- Simplify a fraction to it's reduced formsplit/1
- Extract the whole value portion and the remainer portion of a fraction as a tupleto_float/2
- Convert a fraction to a floating point value
iex> Fraction.new(88, 28) |> Fraction.simplify() |> Fraction.split()
{3, %Fraction{num: 1, den: 7}}
iex> Fraction.new(22, 7) |> Fraction.to_float(precision: 2)
3.14
Aggregate Functions
Work with multiple fractions in aggregate. Most aggregate functions will work with Fractions, or any
value that can be converted to a fraction with new/1
.
clamp/2
- Constrain a list of values to be within a specific rangefractionalize/1
- Convert a list of fraction representations (anything that works withnew/1
) into Fraction structsmax_of/1
- Find the largest value in a list of fractions, or literals compatible withnew/1
min_of/1
- Find the smallest value in a list of fractions, or literals compatible withnew/1
min_max_of/1
- Find the smallest and largest values in a list of fractions or literals compatible withnew/1
normalize/2
- Convert two fractions to a common denominatornormalize_all/1
- Convert a list of two or more fractions to a common denominatorsort/2
- Sort a list of values as fractionssum/2
- Find the sum of a list of fractionsuniq/2
- Extract unique fractions from a list of values
iex> Fraction.normalize(Fraction.new(22, 7), Fraction.new(4, 3))
{ %Fraction{num: 66, den: 21}, %Fraction{num: 28, den: 21} }
iex> Fraction.max_of(["3/4", {4, 5}, 1.5])
%Fraction{num: 15, den: 10}
Inspection
Inspect the properties of individual fractions.
has_whole?/1
- Does a fraction have a whole value component? (i.e. has a total value greater than1
)is_negative?/1
- Is a fraction negative?is_positive?/1
- Is a fraction positive?is_simplified?/1
- Is a fraction in it's simplified form?is_whole?/1
- Is the fraction an exact whole number?is_zero?/1
- Is the fraction zero?
iex> Fraction.new(3, 18) |> is_simplified?()
false
Link to this section Summary
Functions
Get the absolute value of a fraction.
Add two fractions, or a fraction and a value, and return the (optionally simplified) result.
Find the ceiling of a fractional value.
Constrain a list of values as fraction to only those values within the specified min and max.
Extract the numerator and denominator of a fraction as a tuple of values.
Decrement the numerator or denominator by one.
Divide two fractions, or a fraction and a value and return the (optionally simplified) result.
Compare a fraction with a value or fraction using equals comparison.
Find the floor of a fractional value.
Take a mixed list of fraction representations %Fraction{}, integer, float, string, etc), and convert all to fractions. This is not a normalization process - the resulting fractions are not guaranteed to share a denominator.
Get the fractional part left after removing any whole components from the fraction.
Get the whole component of a fraction.
Compare a fraction with a value or fraction using greater than comparison.
Compare a fraction with a value or fraction using greater than or equal comparison.
Determine if a fraction is greater than 1, and has a whole number component.
Increment the numerator or denominator by one.
Determine if a fraction is negative.
Determine if a fraction is positive.
Determine if a fraction is in simplified form.
Determine if a fraction exactly represents a whole number, with no remainder.
Does a fraction represent a zero value?
Compare a fraction with a value or fraction using less than comparison.
Compare a fraction with a value or fraction using less than or equal comparison.
Return the maximum value in a list of fractions or values. Relative comparisons are calculated based on float converion of fractions.
Return the larger of two fractions or values.
Return a tuple with the smallest and largest fractions from a list.
Find the minimum value in a list of fractions or vaules. Relative comparisons are calculated based on float conversion of fractions.
Return the smaller of two fractions, or a fraction and an alternate encoding (like float, string, or integer).
Multiply two fractions, or a fraction and a value and return the (optionally simplified) result.
Determine if two fractions close enough in value.
Convert a string encoding of an integer, float, or fraction into a fraction.
Convert a floating point value to a fraction.
Change a combination of fractions, or fractions and integers, into the same denominator.
Normalize (move to the same denominator) all of the fractions and integers in a list.
Use fractions in power/exponent calculations.
Create the reciprocal of a fraction, optionally simplifying the result.
Round a fraction to the nearest whole value.
Simplify a fraction.
Sort a list of values.
Break a fraction into whole and fractional parts, returning both.
Subtract two fractions, or a fraction an a value, and return the (optionally) simplified result.
Add a series of fractions and integers.
Convert a fraction to a float, optionally rounding to a specific precision.
Return only the unique fractions from a list of values.
Determine if a fraction falls within a specific range.
Determine if a fraction falls within a specified lower and upper bound.
Link to this section Functions
Get the absolute value of a fraction.
Supports Type Coercion?: ✅
Examples
iex> Fraction.new("-34/9") |> Fraction.absolute_value()
%Fraction{num: 34, den: 9}
iex> Fraction.absolute_value("-44/7")
%Fraction{num: 44, den: 7}
Add two fractions, or a fraction and a value, and return the (optionally simplified) result.
Supports Type Coercion?: ✅
Options
simplify
- Boolean - defaultfalse
. Return result as a simplified fraction.
Examples
iex> Fraction.add(Fraction.new(1, 2), Fraction.new(-8, 3))
%Fraction{num: -13, den: 6}
iex> Fraction.add(Fraction.new(3, 4), Fraction.new(3, 4), simplify: true)
%Fraction{num: 3, den: 2}
iex> Fraction.add(Fraction.new(1, 3), 5)
%Fraction{num: 16, den: 3}
iex> Fraction.add(2, Fraction.new(5, 4))
%Fraction{num: 13, den: 4}
iex> Fraction.add("2/3", Fraction.new(5, 3))
%Fraction{num: 7, den: 3}
Find the ceiling of a fractional value.
The ceiling of n
, or ⌈n⌉
, rounds a fractional value up to the nearest whole value.
Supports Type Coercion?: ✅
Examples
iex> Fraction.new("7/8") |> Fraction.ceiling()
%Fraction{num: 8, den: 8}
iex> Fraction.new("0/17") |> Fraction.ceiling()
%Fraction{num: 0, den: 17}
iex> Fraction.new("-47/3") |> Fraction.ceiling()
%Fraction{num: -45, den: 3}
iex> Fraction.ceiling(-3.5)
%Fraction{num: -30, den: 10}
Constrain a list of values as fraction to only those values within the specified min and max.
Values that are not yet Fractions are coerced into fractional values before processing.
Supports Type Coercion?: ✅
Options
min
- Minimum value for constraining value list. Can be any value that is handled bynew/1
max
- Maximum value for constraining value list. Can be any value that is handled bynew/1
min_inclusive
- Boolean. Defaulttrue
. Use inclusive minimum constraint (values>=
min), otherwise use exclusive (values>
min).max_inclusive
- Boolean. Defaulttrue
. Use inclusive maximum constraint (values<=
max), otherwise use exclusive (values<
max).
Examples
iex> Fraction.clamp(["22/7", "14/7", "11/7", "7/7"], min: 1, max: 2, inclusive_max: false)
[%Fraction{num: 11, den: 7}, %Fraction{num: 7, den: 7}]
iex> Fraction.clamp(["22/7", "14/7", "11/7", "7/7"], min: 1, max: 2, inclusive_min: false)
[%Fraction{num: 14, den: 7}, %Fraction{num: 11, den: 7}]
Extract the numerator and denominator of a fraction as a tuple of values.
Examples
iex> Fraction.new(1, 37) |> Fraction.components()
{1, 37}
iex> Fraction.new(0, 3) |> Fraction.components()
{0, 3}
Decrement the numerator or denominator by one.
This is not necessarily an arithmatically valid operation, rather it directly decrements the numerator or denominator. If the decrement would create an invalid denominator, it will return an error instead.
Valid mode
values are: :both
, :num
, :numerator
, :den
, or :denominator
. Note that when decrementing
a negative value by the numerator, the value will move away from 0
, towards the negative.
Examples
iex> Fraction.new("7/11") |> Fraction.decrement(:num)
%Fraction{num: 6, den: 11}
iex> Fraction.new("-5/9") |> Fraction.decrement(:den)
%Fraction{num: -5, den: 8}
iex> Fraction.new("-7/3") |> Fraction.decrement(:numerator)
%Fraction{num: -8, den: 3}
iex> Fraction.new("47/1") |> Fraction.decrement(:denominator)
{:error, :invalid_denominator}
iex> Fraction.new("-21/4") |> Fraction.decrement(:both)
%Fraction{num: -22, den: 3}
Divide two fractions, or a fraction and a value and return the (optionally simplified) result.
Supports Type Coercion?: ✅
Options
simplify
- Boolean - defaultfalse
. Return result as a simplified fraction.
Examples
iex> Fraction.divide(Fraction.new(3, 4), Fraction.new(-7, 2))
%Fraction{num: -6, den: 28}
iex> Fraction.divide(Fraction.new(28, 4), 4, simplify: true)
%Fraction{num: 7, den: 4}
iex> Fraction.divide(60, Fraction.new(7, 12))
%Fraction{num: 720, den: 7}
iex> Fraction.divide(Fraction.new(11, 17), "3")
%Fraction{num: 11, den: 51}
Compare a fraction with a value or fraction using equals comparison.
Supports Type Coercion?: ✅
Examples
iex> Fraction.eq?(Fraction.new(7, 9), Fraction.new(3, 5))
false
iex> Fraction.eq?(3, Fraction.new(12, 4))
true
iex> Fraction.eq?(Fraction.new(-3, 12), -2)
false
Find the floor of a fractional value.
The floor of n
, or ⌊n⌋
, rounds a fractional value down to the nearest whole value.
Supports Type Coercion?: ✅
Examples
iex> Fraction.new("17/8") |> Fraction.floor()
%Fraction{num: 16, den: 8}
iex> Fraction.new("3/5") |> Fraction.floor()
%Fraction{num: 0, den: 5}
iex> Fraction.new("-17/9") |> Fraction.floor()
%Fraction{num: -18, den: 9}
iex> Fraction.floor("31/8")
%Fraction{num: 24, den: 8}
Take a mixed list of fraction representations %Fraction{}, integer, float, string, etc), and convert all to fractions. This is not a normalization process - the resulting fractions are not guaranteed to share a denominator.
Supports Type Coercion?: ✅
Example
iex> fractionalize([%Fraction{num: 3, den: 4}, 12, 0.25, "22/7", "4"])
[%Fraction{num: 3, den: 4}, %Fraction{num: 12, den: 1}, %Fraction{num: 25, den: 100}, %Fraction{num: 22, den: 7}, %Fraction{num: 4, den: 1}]
Get the fractional part left after removing any whole components from the fraction.
Example
iex> Fraction.new(3, 45) |> Fraction.get_remainder()
%Fraction{num: 3, den: 45}
iex> Fraction.new(7, 3) |> Fraction.get_remainder()
%Fraction{num: 1, den: 3}
iex> Fraction.new(-10, 4) |> Fraction.get_remainder()
%Fraction{num: -2, den: 4}
Get the whole component of a fraction.
Examples
iex> Fraction.new(3, 7) |> Fraction.get_whole()
0
iex> Fraction.new(22, 7) |> Fraction.get_whole()
3
iex> Fraction.new(-10, 2) |> Fraction.get_whole()
-5
Compare a fraction with a value or fraction using greater than comparison.
Supports Type Coercion?: ✅
Examples
iex> Fraction.gt?(Fraction.new(7, 9), Fraction.new(3, 5))
true
iex> Fraction.gt?(3, Fraction.new(15, 4))
false
iex> Fraction.gt?(Fraction.new(-3, 12), -2)
true
Compare a fraction with a value or fraction using greater than or equal comparison.
Supports Type Coercion?: ✅
Examples
iex> Fraction.gte?(Fraction.new(3, 9), Fraction.new(1, 3))
true
iex> Fraction.gte?(3, Fraction.new(15, 4))
false
iex> Fraction.gte?(Fraction.new(-3, 12), -2)
true
Determine if a fraction is greater than 1, and has a whole number component.
Examples
iex> Fraction.new(3, 17) |> Fraction.has_whole?()
false
iex> Fraction.new(22, 7) |> Fraction.has_whole?()
true
Increment the numerator or denominator by one.
This is not necessarily an arithmatically valid operation, rather it directly increments the numerator or denominator.
Valid mode
values are: :both
, :num
, :numerator
, :den
, or :denominator
. Note that when incrementing
a negative value by the numerator, the value will move towards 0
, not towards the negative.
Examples
iex> Fraction.new("7/11") |> Fraction.increment(:num)
%Fraction{num: 8, den: 11}
iex> Fraction.new("-5/9") |> Fraction.increment(:den)
%Fraction{num: -5, den: 10}
iex> Fraction.new("-7/3") |> Fraction.increment(:numerator)
%Fraction{num: -6, den: 3}
iex> Fraction.new("21/6") |> Fraction.increment(:both)
%Fraction{num: 22, den: 7}
Determine if a fraction is negative.
Examples
iex> Fraction.new(-3, 4) |> Fraction.is_negative?()
true
Determine if a fraction is positive.
Examples
iex> Fraction.new(-3, 4) |> Fraction.is_positive?()
false
Determine if a fraction is in simplified form.
Examples
iex> Fraction.new(2, 4) |> Fraction.is_simplified?()
false
iex> Fraction.new(-10, 4) |> Fraction.is_simplified?()
false
iex> Fraction.new(0, 7) |> Fraction.is_simplified?()
false
iex> Fraction.new(22, 7) |> Fraction.is_simplified?()
true
Determine if a fraction exactly represents a whole number, with no remainder.
Examples
iex> Fraction.new(5, 3) |> Fraction.is_whole?()
false
iex> Fraction.new(-22, 11) |> Fraction.is_whole?()
true
Does a fraction represent a zero value?
Examples
iex> Fraction.new(3, 134) |> Fraction.is_zero?()
false
iex> Fraction.new(0, 34) |> Fraction.is_zero?()
true
Compare a fraction with a value or fraction using less than comparison.
Supports Type Coercion?: ✅
Examples
iex> Fraction.lt?(Fraction.new(7, 9), Fraction.new(3, 5))
false
iex> Fraction.lt?(3, Fraction.new(15, 4))
true
iex> Fraction.lt?(Fraction.new(-3, 12), -2)
false
Compare a fraction with a value or fraction using less than or equal comparison.
Supports Type Coercion?: ✅
Examples
iex> Fraction.lte?(Fraction.new(7, 9), Fraction.new(3, 5))
false
iex> Fraction.lte?(3, Fraction.new(15, 4))
true
iex> Fraction.lte?(Fraction.new(-24, 12), -2)
true
Return the maximum value in a list of fractions or values. Relative comparisons are calculated based on float converion of fractions.
Supports Type Coercion?: ✅
Example
iex> Fraction.max_of([ Fraction.new(3, 7), Fraction.new(5, 11), Fraction.new(11, 23)])
%Fraction{num: 11, den: 23}
Return the larger of two fractions or values.
Supports Type Coercion?: ✅
Example
iex> Fraction.max_of( Fraction.new(3, 7), Fraction.new(11, 28) )
%Fraction{num: 3, den: 7}
iex> Fraction.max_of(Fraction.new(4, 3), 8.3)
%Fraction{num: 83, den: 10}
Return a tuple with the smallest and largest fractions from a list.
Supports Type Coercion?: ✅
Example
iex> Fraction.min_max_of([ Fraction.new(3, 7), Fraction.new(5, 11), Fraction.new(11, 23)])
{ %Fraction{num: 3, den: 7}, %Fraction{num: 11, den: 23} }
Find the minimum value in a list of fractions or vaules. Relative comparisons are calculated based on float conversion of fractions.
Supports Type Coercion?: ✅
Example
iex> Fraction.min_of([ Fraction.new(3, 7), Fraction.new(5, 11), Fraction.new(11, 23)])
%Fraction{num: 3, den: 7}
Return the smaller of two fractions, or a fraction and an alternate encoding (like float, string, or integer).
Supports Type Coercion?: ✅
Example
iex> Fraction.min_of( Fraction.new(3, 7), Fraction.new(11, 28) )
%Fraction{num: 11, den: 28}
iex> Fraction.min_of( Fraction.new(22, 7), "3/7")
%Fraction{num: 3, den: 7}
iex> Fraction.min_of(0.5, Fraction.new(-3, 5))
%Fraction{num: -3, den: 5}
iex> Fraction.min_of(Fraction.new(3), "22/7")
%Fraction{num: 3, den: 1}
Multiply two fractions, or a fraction and a value and return the (optionally simplified) result.
Supports Type Coercion?: ✅
Options
simplify
- Boolean - defaultfalse
. Return result as a simplified fraction.
Examples
iex> Fraction.multiply(Fraction.new(3, 7), Fraction.new(22, 7))
%Fraction{num: 66, den: 49}
iex> Fraction.multiply(Fraction.new(2, 9), 33, simplify: true)
%Fraction{num: 22, den: 3}
iex> Fraction.multiply(4, Fraction.new(12, 5))
%Fraction{num: 48, den: 5}
iex> Fraction.multiply("4", Fraction.new(22, 7))
%Fraction{num: 88, den: 7}
Determine if two fractions close enough in value.
This is similar to doing floating point comparison, where an epsilon value is used to determine if two values are within a given range of each other.
In this case, we test if the difference between the first two fractions is less than or equal
to the third fraction. So, if we wanted to determine if 3/2
and 5/3
were within 1/4
of each
other, or had a difference less than or equal to 1/4
:
iex> Fraction.near_equal?("3/2", "5/3", "1/4")
true
Examples
iex> Fraction.near_equal?("1/10", "8/10", 0.05)
false
iex> Fraction.near_equal?("-1/3", "4/3", 2)
true
Convert a string encoding of an integer, float, or fraction into a fraction.
Example
iex> Fraction.new("3")
%Fraction{num: 3, den: 1}
iex> Fraction.new("12/7")
%Fraction{num: 12, den: 7}
iex> Fraction.new("13 / 5")
%Fraction{num: 13, den: 5}
iex> Fraction.new("foo/bar")
{:error, :no_parsable_fraction}
iex> Fraction.new("3.14")
%Fraction{num: 314, den: 100}
Convert a floating point value to a fraction.
There are two modes for converting values:
- Using precision approximation (via
Float.ratio/1
) - Using natural conversion
Natural conversion tries to find a fraction that represents the intended value of
a float, while precision approximation tries to find a fractional representation of
the encoded floating point value. Use the conversion
flag to toggle between
the two modes.
Flags
conversion
- Atom. One of:natural
or:precision
Example
iex> Fraction.new(0.9, conversion: :natural) |> to_string()
"9/10"
iex> Fraction.new(0.9, conversion: :precision) |> to_string()
"8106479329266893/9007199254740992"
iex> Fraction.new(3.14, conversion: :natural) |> to_string()
"314/100"
iex> Fraction.new(3.14, conversion: :precision) |> to_string()
"7070651414971679/2251799813685248"
Change a combination of fractions, or fractions and integers, into the same denominator.
Example
iex> Fraction.normalize(Fraction.new(3, 4), Fraction.new(1, 7))
{ %Fraction{num: 21, den: 28}, %Fraction{num: 4, den: 28} }
iex> Fraction.normalize(3, Fraction.new(2, 5))
{ %Fraction{num: 15, den: 5}, %Fraction{num: 2, den: 5} }
iex> Fraction.normalize(Fraction.new(6, 4), 2)
{ %Fraction{num: 6, den: 4}, %Fraction{num: 8, den: 4} }
Normalize (move to the same denominator) all of the fractions and integers in a list.
Supports Type Coercion?: ✅
Examples
iex> Fraction.normalize_all([Fraction.new(1, 2), Fraction.new(2, 3), Fraction.new(3, 4), 7])
[
%Fraction{den: 12, num: 6},
%Fraction{den: 12, num: 8},
%Fraction{den: 12, num: 9},
%Fraction{den: 12, num: 84}
]
iex> Fraction.normalize_all(["3/4", {7, 8}, Fraction.new(8, 16)])
[
%Fraction{num: 12, den: 16},
%Fraction{num: 14, den: 16},
%Fraction{num: 8, den: 16}
]
Use fractions in power/exponent calculations.
The base or the power (or both) can be fractions.
Fractions taken to an integer power will behave as expected:
iex> Fraction.power(Fraction.new(3, 4), 7)
%Chunky.Fraction{den: 16384, num: 2187}
Fractions or integers taken to a fractional power will not always return expected values, as most fractional powers do not have a result that can be represented as a fraction. By default the power functions will return an error value in these cases:
iex> Fraction.power(9, Fraction.new(7, 13))
{:error, :no_fractional_power}
If you want the floating point fractional result, you can use the allow_irrational
flag:
iex> Fraction.power(9, Fraction.new(7, 13), allow_irrational: true)
3.26454673038995
When calculating the fractional power of a value, an epsilon
value is used as part
of the n-th root finding and resulting analysis The epsilon determines how close to
a whole number different components of the resulting fractions need to be, to be treated
as whole numbers.
Options
simplify
- Boolean. Defaultfalse
. Optionally simplify the return fractionepsilon
- Float. Small number used to compare how close two values areallow_irrational
- Boolean. eDefaultfalse
. Allow a non-fractional (irrational) result to be returned
Examples
iex> Fraction.power(Fraction.new(7, 32), Fraction.new(30, 5))
%Fraction{num: 117649, den: 1073741824}
iex> Fraction.power(Fraction.new(3, 5), 3)
%Fraction{num: 27, den: 125}
iex> Fraction.power(4, Fraction.new(-4, 8))
%Fraction{num: 1, den: 2}
iex> Fraction.power(9, Fraction.new(7, 13), allow_irrational: true)
3.26454673038995
iex> Fraction.power("3/8", 2.0)
%Fraction{num: 9, den: 64}
Create the reciprocal of a fraction, optionally simplifying the result.
Negative fractions will switch the sign to carry on the new numerator. Trying to take the reciprocal of a zero fraction will result in an error.
Options
simplify
- Boolean - defaultfalse
. Return result as a simplified fraction.
Examples
iex> Fraction.new(3, 4) |> Fraction.reciprocal()
%Fraction{num: 4, den: 3}
iex> Fraction.new(-4, 40) |> Fraction.reciprocal(simplify: true)
%Fraction{num: -10, den: 1}
iex> Fraction.new(0, 3) |> Fraction.reciprocal()
{:error, :invalid_denominator}
Round a fraction to the nearest whole value.
This round function uses the "round half away from zero" strategy, which differs from standard IEEE-754 floating point rounding mode, as we don't lose precision as fractions grow. Using this round method avoids introducing even/odd bias over multiple calculations.
Supports Type Coercion?: ✅
Examples
iex> Fraction.round("22/7")
%Fraction{num: 21, den: 7}
iex> Fraction.round("-13/8")
%Fraction{num: -16, den: 8}
Simplify a fraction.
Examples
iex> Fraction.new(6, 8) |> Fraction.simplify()
%Fraction{num: 3, den: 4}
iex> Fraction.new(24, 8) |> Fraction.simplify()
%Fraction{num: 3, den: 1}
iex> Fraction.new(22, 7) |> Fraction.simplify()
%Fraction{num: 22, den: 7}
Sort a list of values.
Values that are not yet Fractions are coerced into fractional values before processing.
Supports Type Coercion?: ✅
Sorting is done based on floating point values of fractions.
Options
sorter
- Function arity 2. Default&<=/2
. Comparison to use when sorting.
Examples
iex> Fraction.sort(["22/7", 3, "2.9", Fraction.new(1, 3)])
[%Fraction{num: 1, den: 3}, %Fraction{num: 29, den: 10}, %Fraction{num: 3, den: 1}, %Fraction{num: 22, den: 7}]
iex> Fraction.sort(["22/7", 3, "2.9", Fraction.new(1, 3)], sorter: &>=/2)
[%Fraction{num: 22, den: 7}, %Fraction{num: 3, den: 1}, %Fraction{num: 29, den: 10}, %Fraction{num: 1, den: 3}]
Break a fraction into whole and fractional parts, returning both.
Examples
iex> Fraction.new(6, 4) |> Fraction.split()
{1, %Fraction{num: 2, den: 4}}
iex> Fraction.new(-22, 7) |> Fraction.split()
{-3, %Fraction{num: -1, den: 7}}
iex> Fraction.new(0, 3) |> Fraction.split()
{0, %Fraction{num: 0, den: 3}}
Subtract two fractions, or a fraction an a value, and return the (optionally) simplified result.
Supports Type Coercion?: ✅
Options
simplify
- Boolean - defaultfalse
. Return result as a simplified fraction.
Examples
iex> Fraction.subtract(Fraction.new(3, 5), Fraction.new(1, 5))
%Fraction{num: 2, den: 5}
iex> Fraction.subtract(2, Fraction.new(-6, 9), simplify: true)
%Fraction{num: 8, den: 3}
iex> Fraction.subtract(Fraction.new(-2, 4), -5, simplify: true)
%Fraction{num: 9, den: 2}
iex> Fraction.subtract(Fraction.new(8, 10), 0.5)
%Fraction{num: 3, den: 10}
Add a series of fractions and integers.
Supports Type Coercion?: ✅
Options
simplify
- Boolean - defaultfalse
. Return result as a simplified fraction.
Example
iex> Fraction.sum([Fraction.new(3, 4), Fraction.new(5, 7), Fraction.new(8, 11), 1, Fraction.new(249, 308)])
%Fraction{num: 1232, den: 308}
iex> Fraction.sum([Fraction.new(3, 4), Fraction.new(5, 7), Fraction.new(8, 11), 1, Fraction.new(249, 308)], simplify: true)
%Fraction{num: 4, den: 1}
Convert a fraction to a float, optionally rounding to a specific precision.
Options
precision
- Integer. Default15
. Number of digits of precision in float. From0
to15
.
Examples
iex> Fraction.new(22, 7) |> to_float()
3.142857142857143
iex> Fraction.new(22, 7) |> to_float(precision: 2)
3.14
Return only the unique fractions from a list of values.
Values that are not yet Fractions are coerced into fractional values before processing.
Supports Type Coercion?: ✅
Determining what is unique from the list of values is controlled
by the by
option. By default, value
comparison is used, so 1/2
and 2/4
would
be equal, and only one returned. If components
comparison is specified,
the literal numerator and denominator must match, so non-simplified, but value
equal fractions would be different from one another.
Options
by
- Either:value
or:components
. Default:value
.
Examples
iex> Fraction.uniq(["2/4", Fraction.new(4, 2), 2, 0.5])
[%Fraction{num: 2, den: 4}, %Fraction{num: 4, den: 2}]
iex> Fraction.uniq(["2/4", Fraction.new(4, 2), 2, 0.5], by: :components)
[%Fraction{num: 2, den: 4}, %Fraction{num: 4, den: 2}, %Fraction{num: 2, den: 1}, %Fraction{num: 5, den: 10}]
Determine if a fraction falls within a specific range.
Supports Type Coercion?: ✅
Examples
iex> Fraction.new("22/7") |> Fraction.within?(3..4)
true
iex> Fraction.new("3/5") |> Fraction.within?(-1..1)
true
iex> Fraction.within?(3.1, 1..5)
true
Determine if a fraction falls within a specified lower and upper bound.
This test is inclusive of the lower and upper bounds. The low and high value of the range to test can be specified as any coercible value.
Supports Type Coercion?: ✅
Examples
iex> Fraction.new("22/7") |> Fraction.within?(3, 4.5)
true
iex> Fraction.new("-4/3") |> Fraction.within?("-10/3", "-4/3")
true
iex> Fraction.within?("22/7", -3, 4)
true