fus 2.4.1
import "./main" all

# Many degree methods and radian methods are independent, to avoid degrees approximation.

# Useful when come across a computed value like 179.9999999. ==========[
approxEquals'export: (ns, a, b) ->
    # 8388608 (23 bits) is the precision of single-floating-point. So
    # if they are equal in single-precision, they can be considered as
    # approximately equal in double-precision.
    threshold: 1 / 8388608
    ratioThreshold: 1 + threshold

    if Math.abs(a) < threshold or Math.abs(b) < threshold
        Math.abs(a - b) < threshold
    else
        1 / ratioThreshold < a / b < ratioThreshold

approxGreaterThan'export: (ns, a, b) -> a > b or Math..approxEquals(a, b)
approxLessThan'export: (ns, a, b) -> a < b or Math..approxEquals(a, b)
# ]========================================

radiansToDegrees'export: (ns, radians) -> radians / Math.PI * 180
degreesToRadians'export: (ns, degrees) -> degrees / 180 * Math.PI

principalRadians'export: (ns, radians) ->
    t: radians rem (2 * Math.PI)
    if t ≤ -Math.PI
        t + 2 * Math.PI
    else if t > Math.PI
        t - 2 * Math.PI
    else
        t
principalDegrees'export: (ns, degrees) ->
    t: degrees rem 360
    if t ≤ -180
        t + 360
    else if t > 180
        t - 360
    else
        t

roundDecimal'export: (ns, x, digitCount: 0) ->
    factor: Math.pow(10, digitCount)
    Math.round(x * factor) / factor

# Returns a random number x where m≤x<n.
randomNumber'export: (ns, m, n) -> m < n ? m + Math.random() * (n - m) | fail()

# If n is omitted, returns a random integer x where 0≤x<m.
# If n is not omitted, Returns a random integer x where m≤x<n.
randomInt'export: (ns, m, n) ->
    min: n = void ? 0 | m
    max: n = void ? m | n
    Math.floor(Math..randomNumber(min, max))
