Convenience functions for dealing with Floats.
aboutEqual : Basics.Float -> Basics.Float -> Basics.Bool
Comparing Floats with ==
is usually wrong, unless you basically care for reference equality, since floating point
numbers often have small precision drift.
0.1 + 0.2 == 0.3 --> False
This function implements an approximation where we are asking - are these values close enough that we can consider their difference to be due to floating point drift rather than a result of meaningful difference in calculation?
(0.1 + 0.2) |> Float.Extra.aboutEqual 0.3 --> True
Note: this is unlikely to be appropriate if you are performing computations much smaller than one.
(0.00001 + 0.00002) |> Float.Extra.aboutEqual 0.00003 --> True
This value handles Infinity and NaN like so:
(1 / 0) |> Float.Extra.aboutEqual (100 / 0) --> True
(0 / 0) |> Float.Extra.aboutEqual (0 / 0) --> False
toFixedDecimalPlaces : Basics.Int -> Basics.Float -> String
Fix a float value represented to a certain number of decimal places as a string.
Float.Extra.toFixedDecimalPlaces 3 0.0326232 --> "0.033"
toFixedSignificantDigits : Basics.Int -> Basics.Float -> String
Fix a float value represented as a string to a certain number of significant digits.
Float.Extra.toFixedSignificantDigits 2 1.435 --> "1.4"
Float.Extra.toFixedSignificantDigits 2 545435 --> "550000"
Float.Extra.toFixedSignificantDigits 2 0.0039 --> "0.0039"
boundaryValuesAsUnicode : (Basics.Float -> String) -> Basics.Float -> String
When showing Float values to users, we generally don't particularly want them to see programmer-y values like
NaN
or Infinity
. This function wraps a number formatting routine, but replaces those values with unicode symbols:
format : Float -> String
format =
Float.Extra.toFixedSignificantDigits 3
|> Float.Extra.boundaryValuesAsUnicode
format (0 / 0) --> "∅"
format (1 / 0) --> "∞"
format (-1 / 0) --> "-∞"
format (1 / 3) -> "0.333"
Of course using this is unsuitable for when you want the numbers to be machine readable.
range : Basics.Float -> Basics.Float -> Basics.Float -> List Basics.Float
Returns a List containing an arithmetic progression, similar to the Python built-in range.
Takes a start
, stop
and step
argument. The stop value is exclusive; it is not
included in the result. If step
is positive, the last element is the largest
start + i * step
less than stop
; if step
is negative, the last element is
the smallest start + i * step
greater than stop
. If the returned list would
contain an infinite number of values, an empty range is returned.
The arguments are not required to be whole numbers; however, the results are more predictable if they are.
Differences from List.range from the standard library:
List.range
is inclusive, meaning that the stop value will be included in the resultList.range
supports Int
, whereas this uses Float
List.range
supports only increasing intervals (i.e. List.range 3 1 == []
vs. range 3 1 -1 == [3, 2]
)List.range
doesn't allow for specifying the step valuemodBy : Basics.Float -> Basics.Float -> Basics.Float
Perform modular arithmetic involving floating point numbers.
The sign of the result is the same as the sign of the modulus
in Float.Extra.modBy modulus x
.
Float.Extra.modBy 2.5 5 --> 0
Float.Extra.modBy 2 4.5 == 0.5
Float.Extra.modBy 2 -4.5 == 1.5
Float.Extra.modBy -2 4.5 == -1.5