Skip to content

Commit

Permalink
feat(stdlib): Add copySign, sqrt, min, max, round, trunc,…
Browse files Browse the repository at this point in the history
… `floor`, `ceil` to `Float64` (#2162)

Co-authored-by: Oscar Spencer <[email protected]>
Co-authored-by: Oscar Spencer <[email protected]>
  • Loading branch information
3 people authored Sep 21, 2024
1 parent f5a3dd3 commit e99dcba
Show file tree
Hide file tree
Showing 3 changed files with 492 additions and 0 deletions.
64 changes: 64 additions & 0 deletions compiler/test/stdlib/float64.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,24 @@ assert Float64.isInfinite(-1.0d) == false
assert Float64.isInfinite(25.76d) == false
assert Float64.isInfinite(-25.00d) == false

// min
assert Float64.min(5.0d, 5.0d) == 5.0d
assert Float64.min(5.0d, 6.0d) == 5.0d
assert Float64.min(6.0d, 5.0d) == 5.0d
assert Float64.min(0.5d, 0.25d) == 0.25d
assert Float64.min(Infinityd, 10.0d) == 10.0d
assert Float64.isNaN(Float64.min(NaNd, 10.0d))
assert Float64.isNaN(Float64.min(NaNd, Infinityd))

// max
assert Float64.max(5.0d, 5.0d) == 5.0d
assert Float64.max(6.0d, 5.0d) == 6.0d
assert Float64.max(5.0d, 6.0d) == 6.0d
assert Float64.max(0.5d, 0.2d) == 0.5d
assert Float64.max(Infinityd, 10.0d) == Infinityd
assert Float64.isNaN(Float64.max(NaNd, 10.0d))
assert Float64.isNaN(Float64.max(NaNd, Infinityd))

// abs
assert Float64.abs(-25.5d) == 25.5d
assert Float64.abs(25.5d) == 25.5d
Expand All @@ -147,3 +165,49 @@ assert Float64.neg(-25.5d) == 25.5d
assert Float64.neg(25.5d) == -25.5d
assert Float64.isNaN(-NaNd)
assert Float64.neg(Infinityd) == -Infinityd

// ceil
assert Float64.ceil(-25.5d) == -25.0d
assert Float64.ceil(25.5d) == 26.0d
assert Float64.ceil(25.0d) == 25.0d
assert Float64.isNaN(Float64.ceil(NaNd))
assert Float64.ceil(Infinityd) == Infinityd
// floor
assert Float64.floor(-25.5d) == -26.0d
assert Float64.floor(25.5d) == 25.0d
assert Float64.floor(25.0d) == 25.0d
assert Float64.isNaN(Float64.floor(NaNd))
assert Float64.floor(Infinityd) == Infinityd
// trunc
assert Float64.trunc(-25.5d) == -25.0d
assert Float64.trunc(25.5d) == 25.0d
assert Float64.trunc(25.0d) == 25.0d
assert Float64.isNaN(Float64.trunc(NaNd))
assert Float64.trunc(Infinityd) == Infinityd
// round
assert Float64.round(-25.5d) == -26.0d
assert Float64.round(-25.25d) == -25.0d
assert Float64.round(25.25d) == 25.0d
assert Float64.round(25.5d) == 26.0d
assert Float64.isNaN(Float64.round(NaNd))
assert Float64.round(Infinityd) == Infinityd
// sqrt
assert Float64.sqrt(25.0d) == 5.0d
assert Float64.sqrt(35.0d) == 5.916079783099616d
assert Float64.sqrt(9266609011276477657.0d) == 3044110545.180066d
assert Float64.sqrt(Infinityd) == Infinityd
assert Float64.isNaN(Float64.sqrt(NaNd))
// copySign
assert Float64.copySign(2.0d, 1.0d) == 2.0d
assert Float64.copySign(-2.0d, 1.0d) == 2.0d
assert Float64.copySign(1.0d, 2.0d) == 1.0d
assert Float64.copySign(2.0d, -1.0d) == -2.0d
assert Float64.copySign(1.0d, -2.0d) == -1.0d
assert Float64.copySign(Infinityd, 1.0d) == Infinityd
assert Float64.copySign(Infinityd, -1.0d) == -Infinityd
assert Float64.copySign(1.0d, Infinityd) == 1.0d
assert Float64.copySign(1.0d, -Infinityd) == -1.0d
assert Float64.isNaN(Float64.copySign(NaNd, 1.0d))
assert Float64.isNaN(Float64.copySign(NaNd, -1.0d))
assert Float64.copySign(1.0d, NaNd) == 1.0d
assert Float64.copySign(1.0d, -NaNd) == -1.0d
149 changes: 149 additions & 0 deletions stdlib/float64.gr
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,44 @@ provide let isNaN = (x: Float64) => x != x
*/
provide let isInfinite = (x: Float64) => x == Infinityd || x == -Infinityd

/**
* Returns the smaller of its operands.
*
* @param x: The first operand
* @param y: The second operand
* @returns The smaller of the two operands
*
* @example Float64.min(5.0d, 2.0d) == 2.0d
*
* @since v0.7.0
*/
@unsafe
provide let min = (x: Float64, y: Float64) => {
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmF64.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newFloat64(WasmF64.min(xv, yv))
WasmI32.toGrain(ptr): Float64
}

/**
* Returns the larger of its operands.
*
* @param x: The first operand
* @param y: The second operand
* @returns The larger of the two operands
*
* @example Float64.max(5.0d, 2.0d) == 5.0d
*
* @since v0.7.0
*/
@unsafe
provide let max = (x: Float64, y: Float64) => {
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmF64.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newFloat64(WasmF64.max(xv, yv))
WasmI32.toGrain(ptr): Float64
}

/**
* Returns the absolute value. That is, it returns `x` if `x` is positive or zero and the negation of `x` if `x` is negative.
*
Expand Down Expand Up @@ -336,3 +374,114 @@ provide let neg = (x: Float64) => {
let ptr = newFloat64(WasmF64.neg(xv))
WasmI32.toGrain(ptr): Float64
}

/**
* Rounds its operand up to the next largest whole value.
*
* @param x: The operand to ceil
* @returns The next largest whole value of the operand
*
* @example Float64.ceil(5.5d) == 6.0d
* @example Float64.ceil(-5.5d) == -5.0d
*
* @since v0.7.0
*/
@unsafe
provide let ceil = (x: Float64) => {
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let ptr = newFloat64(WasmF64.ceil(xv))
WasmI32.toGrain(ptr): Float64
}

/**
* Rounds its operand down to the largest whole value less than the operand.
*
* @param x: The operand to floor
* @returns The previous whole value of the operand
*
* @example Float64.floor(5.5d) == 5.0d
* @example Float64.floor(-5.5d) == -6.0d
*
* @since v0.7.0
*/
@unsafe
provide let floor = (x: Float64) => {
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let ptr = newFloat64(WasmF64.floor(xv))
WasmI32.toGrain(ptr): Float64
}

/**
* Returns the whole value part of its operand, removing any fractional value.
*
* @param x: The operand to truncate
* @returns The whole value part of the operand
*
* @example Float64.trunc(5.5d) == 5.0d
*
* @since v0.7.0
*/
@unsafe
provide let trunc = (x: Float64) => {
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let ptr = newFloat64(WasmF64.trunc(xv))
WasmI32.toGrain(ptr): Float64
}

/**
* Returns its operand rounded to its nearest integer.
*
* @param x: The operand to round
* @returns The nearest integer to the operand
*
* @example Float64.round(5.5d) == 6.0d
* @example Float64.round(5.4d) == 5.0d
* @example Float64.round(-5.5d) == -6.0d
* @example Float64.round(-5.4d) == -5.0d
*
* @since v0.7.0
*/
@unsafe
provide let round = (x: Float64) => {
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let ptr = newFloat64(WasmF64.nearest(xv))
WasmI32.toGrain(ptr): Float64
}

/**
* Computes the square root of its operand.
*
* @param x: The operand to square root
* @returns The square root of the operand
*
* @example Float64.sqrt(25.0d) == 5.0d
*
* @since v0.7.0
*/
@unsafe
provide let sqrt = (x: Float64) => {
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let ptr = newFloat64(WasmF64.sqrt(xv))
WasmI32.toGrain(ptr): Float64
}

/**
* Copys the sign of the second operand to the first operand.
*
* @param x: The operand to be modify
* @param y: The operand to copy the sign from
* @returns The first operand with the sign of the second operand
*
* @example Float64.copySign(2.0d, 1.0d) == 2.0d
* @example Float64.copySign(3.0d, -1.0d) == -3.0d
* @example Float64.copySign(-5.0d, 1.0d) == 5.0d
*
* @since v0.7.0
*/
@unsafe
provide let copySign = (x: Float64, y: Float64) => {
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
let yv = WasmF64.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
let ptr = newFloat64(WasmF64.copySign(xv, yv))
WasmI32.toGrain(ptr): Float64
}
Loading

0 comments on commit e99dcba

Please sign in to comment.