elmcraft/core-extra/1.0.0

NOTE: the latest version is 2.3.0

Float.Extra

Convenience functions for dealing with Floats.

Equality

aboutEqual : Float -> Float -> 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

Formatting Floats

toFixedDecimalPlaces : Int -> 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 : Int -> 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 : (Float -> String) -> 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.

Ranges

range : Float -> Float -> Float -> List 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 result
  • List.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 value

Modular arithmetic

modBy : Float -> Float -> 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