Skip to content

Commit e99dcba

Browse files
feat(stdlib): Add copySign, sqrt, min, max, round, trunc, floor, ceil to Float64 (#2162)
Co-authored-by: Oscar Spencer <[email protected]> Co-authored-by: Oscar Spencer <[email protected]>
1 parent f5a3dd3 commit e99dcba

File tree

3 files changed

+492
-0
lines changed

3 files changed

+492
-0
lines changed

compiler/test/stdlib/float64.test.gr

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,24 @@ assert Float64.isInfinite(-1.0d) == false
136136
assert Float64.isInfinite(25.76d) == false
137137
assert Float64.isInfinite(-25.00d) == false
138138

139+
// min
140+
assert Float64.min(5.0d, 5.0d) == 5.0d
141+
assert Float64.min(5.0d, 6.0d) == 5.0d
142+
assert Float64.min(6.0d, 5.0d) == 5.0d
143+
assert Float64.min(0.5d, 0.25d) == 0.25d
144+
assert Float64.min(Infinityd, 10.0d) == 10.0d
145+
assert Float64.isNaN(Float64.min(NaNd, 10.0d))
146+
assert Float64.isNaN(Float64.min(NaNd, Infinityd))
147+
148+
// max
149+
assert Float64.max(5.0d, 5.0d) == 5.0d
150+
assert Float64.max(6.0d, 5.0d) == 6.0d
151+
assert Float64.max(5.0d, 6.0d) == 6.0d
152+
assert Float64.max(0.5d, 0.2d) == 0.5d
153+
assert Float64.max(Infinityd, 10.0d) == Infinityd
154+
assert Float64.isNaN(Float64.max(NaNd, 10.0d))
155+
assert Float64.isNaN(Float64.max(NaNd, Infinityd))
156+
139157
// abs
140158
assert Float64.abs(-25.5d) == 25.5d
141159
assert Float64.abs(25.5d) == 25.5d
@@ -147,3 +165,49 @@ assert Float64.neg(-25.5d) == 25.5d
147165
assert Float64.neg(25.5d) == -25.5d
148166
assert Float64.isNaN(-NaNd)
149167
assert Float64.neg(Infinityd) == -Infinityd
168+
169+
// ceil
170+
assert Float64.ceil(-25.5d) == -25.0d
171+
assert Float64.ceil(25.5d) == 26.0d
172+
assert Float64.ceil(25.0d) == 25.0d
173+
assert Float64.isNaN(Float64.ceil(NaNd))
174+
assert Float64.ceil(Infinityd) == Infinityd
175+
// floor
176+
assert Float64.floor(-25.5d) == -26.0d
177+
assert Float64.floor(25.5d) == 25.0d
178+
assert Float64.floor(25.0d) == 25.0d
179+
assert Float64.isNaN(Float64.floor(NaNd))
180+
assert Float64.floor(Infinityd) == Infinityd
181+
// trunc
182+
assert Float64.trunc(-25.5d) == -25.0d
183+
assert Float64.trunc(25.5d) == 25.0d
184+
assert Float64.trunc(25.0d) == 25.0d
185+
assert Float64.isNaN(Float64.trunc(NaNd))
186+
assert Float64.trunc(Infinityd) == Infinityd
187+
// round
188+
assert Float64.round(-25.5d) == -26.0d
189+
assert Float64.round(-25.25d) == -25.0d
190+
assert Float64.round(25.25d) == 25.0d
191+
assert Float64.round(25.5d) == 26.0d
192+
assert Float64.isNaN(Float64.round(NaNd))
193+
assert Float64.round(Infinityd) == Infinityd
194+
// sqrt
195+
assert Float64.sqrt(25.0d) == 5.0d
196+
assert Float64.sqrt(35.0d) == 5.916079783099616d
197+
assert Float64.sqrt(9266609011276477657.0d) == 3044110545.180066d
198+
assert Float64.sqrt(Infinityd) == Infinityd
199+
assert Float64.isNaN(Float64.sqrt(NaNd))
200+
// copySign
201+
assert Float64.copySign(2.0d, 1.0d) == 2.0d
202+
assert Float64.copySign(-2.0d, 1.0d) == 2.0d
203+
assert Float64.copySign(1.0d, 2.0d) == 1.0d
204+
assert Float64.copySign(2.0d, -1.0d) == -2.0d
205+
assert Float64.copySign(1.0d, -2.0d) == -1.0d
206+
assert Float64.copySign(Infinityd, 1.0d) == Infinityd
207+
assert Float64.copySign(Infinityd, -1.0d) == -Infinityd
208+
assert Float64.copySign(1.0d, Infinityd) == 1.0d
209+
assert Float64.copySign(1.0d, -Infinityd) == -1.0d
210+
assert Float64.isNaN(Float64.copySign(NaNd, 1.0d))
211+
assert Float64.isNaN(Float64.copySign(NaNd, -1.0d))
212+
assert Float64.copySign(1.0d, NaNd) == 1.0d
213+
assert Float64.copySign(1.0d, -NaNd) == -1.0d

stdlib/float64.gr

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,44 @@ provide let isNaN = (x: Float64) => x != x
301301
*/
302302
provide let isInfinite = (x: Float64) => x == Infinityd || x == -Infinityd
303303

304+
/**
305+
* Returns the smaller of its operands.
306+
*
307+
* @param x: The first operand
308+
* @param y: The second operand
309+
* @returns The smaller of the two operands
310+
*
311+
* @example Float64.min(5.0d, 2.0d) == 2.0d
312+
*
313+
* @since v0.7.0
314+
*/
315+
@unsafe
316+
provide let min = (x: Float64, y: Float64) => {
317+
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
318+
let yv = WasmF64.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
319+
let ptr = newFloat64(WasmF64.min(xv, yv))
320+
WasmI32.toGrain(ptr): Float64
321+
}
322+
323+
/**
324+
* Returns the larger of its operands.
325+
*
326+
* @param x: The first operand
327+
* @param y: The second operand
328+
* @returns The larger of the two operands
329+
*
330+
* @example Float64.max(5.0d, 2.0d) == 5.0d
331+
*
332+
* @since v0.7.0
333+
*/
334+
@unsafe
335+
provide let max = (x: Float64, y: Float64) => {
336+
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
337+
let yv = WasmF64.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
338+
let ptr = newFloat64(WasmF64.max(xv, yv))
339+
WasmI32.toGrain(ptr): Float64
340+
}
341+
304342
/**
305343
* Returns the absolute value. That is, it returns `x` if `x` is positive or zero and the negation of `x` if `x` is negative.
306344
*
@@ -336,3 +374,114 @@ provide let neg = (x: Float64) => {
336374
let ptr = newFloat64(WasmF64.neg(xv))
337375
WasmI32.toGrain(ptr): Float64
338376
}
377+
378+
/**
379+
* Rounds its operand up to the next largest whole value.
380+
*
381+
* @param x: The operand to ceil
382+
* @returns The next largest whole value of the operand
383+
*
384+
* @example Float64.ceil(5.5d) == 6.0d
385+
* @example Float64.ceil(-5.5d) == -5.0d
386+
*
387+
* @since v0.7.0
388+
*/
389+
@unsafe
390+
provide let ceil = (x: Float64) => {
391+
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
392+
let ptr = newFloat64(WasmF64.ceil(xv))
393+
WasmI32.toGrain(ptr): Float64
394+
}
395+
396+
/**
397+
* Rounds its operand down to the largest whole value less than the operand.
398+
*
399+
* @param x: The operand to floor
400+
* @returns The previous whole value of the operand
401+
*
402+
* @example Float64.floor(5.5d) == 5.0d
403+
* @example Float64.floor(-5.5d) == -6.0d
404+
*
405+
* @since v0.7.0
406+
*/
407+
@unsafe
408+
provide let floor = (x: Float64) => {
409+
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
410+
let ptr = newFloat64(WasmF64.floor(xv))
411+
WasmI32.toGrain(ptr): Float64
412+
}
413+
414+
/**
415+
* Returns the whole value part of its operand, removing any fractional value.
416+
*
417+
* @param x: The operand to truncate
418+
* @returns The whole value part of the operand
419+
*
420+
* @example Float64.trunc(5.5d) == 5.0d
421+
*
422+
* @since v0.7.0
423+
*/
424+
@unsafe
425+
provide let trunc = (x: Float64) => {
426+
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
427+
let ptr = newFloat64(WasmF64.trunc(xv))
428+
WasmI32.toGrain(ptr): Float64
429+
}
430+
431+
/**
432+
* Returns its operand rounded to its nearest integer.
433+
*
434+
* @param x: The operand to round
435+
* @returns The nearest integer to the operand
436+
*
437+
* @example Float64.round(5.5d) == 6.0d
438+
* @example Float64.round(5.4d) == 5.0d
439+
* @example Float64.round(-5.5d) == -6.0d
440+
* @example Float64.round(-5.4d) == -5.0d
441+
*
442+
* @since v0.7.0
443+
*/
444+
@unsafe
445+
provide let round = (x: Float64) => {
446+
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
447+
let ptr = newFloat64(WasmF64.nearest(xv))
448+
WasmI32.toGrain(ptr): Float64
449+
}
450+
451+
/**
452+
* Computes the square root of its operand.
453+
*
454+
* @param x: The operand to square root
455+
* @returns The square root of the operand
456+
*
457+
* @example Float64.sqrt(25.0d) == 5.0d
458+
*
459+
* @since v0.7.0
460+
*/
461+
@unsafe
462+
provide let sqrt = (x: Float64) => {
463+
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
464+
let ptr = newFloat64(WasmF64.sqrt(xv))
465+
WasmI32.toGrain(ptr): Float64
466+
}
467+
468+
/**
469+
* Copys the sign of the second operand to the first operand.
470+
*
471+
* @param x: The operand to be modify
472+
* @param y: The operand to copy the sign from
473+
* @returns The first operand with the sign of the second operand
474+
*
475+
* @example Float64.copySign(2.0d, 1.0d) == 2.0d
476+
* @example Float64.copySign(3.0d, -1.0d) == -3.0d
477+
* @example Float64.copySign(-5.0d, 1.0d) == 5.0d
478+
*
479+
* @since v0.7.0
480+
*/
481+
@unsafe
482+
provide let copySign = (x: Float64, y: Float64) => {
483+
let xv = WasmF64.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
484+
let yv = WasmF64.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
485+
let ptr = newFloat64(WasmF64.copySign(xv, yv))
486+
WasmI32.toGrain(ptr): Float64
487+
}

0 commit comments

Comments
 (0)