summaryrefslogtreecommitdiff
path: root/lib/math/fpmath.myr
blob: db92b6ee435d65a175383a264f0b4e358d449767 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use std

pkg math =
	trait fpmath @f =

		/* fma-impl */
		fma : (x : @f, y : @f, z : @f -> @f)

		/* sqrt-impl */
		sqrt : (f : @f -> @f)

		/* trunc-impl */
		trunc : (f : @f -> @f)
		ceil  : (f : @f -> @f)
		floor : (f : @f -> @f)

		/* sum-impl */
		kahan_sum : (a : @f[:] -> @f)
		priest_sum : (a : @f[:] -> @f)
	;;

	impl std.equatable flt32
	impl std.equatable flt64
	impl fpmath flt32
	impl fpmath flt64
;;

/*
   We consider two floating-point numbers equal if their bits are
   equal. This does not treat NaNs specially: two distinct NaNs may
   compare equal, or they may compare distinct (if they arise from
   different bit patterns).

   Additionally, +0.0 and -0.0 compare differently.
 */
impl std.equatable flt32 =
	eq = {a : flt32, b : flt32; -> std.flt32bits(a) == std.flt32bits(b)}
;;

impl std.equatable flt64 =
	eq = {a : flt64, b : flt64; -> std.flt64bits(a) == std.flt64bits(b)}
;;

impl fpmath flt32 =
	fma = {x, y, z; -> fma32(x, y, z)}

	sqrt = {f; -> sqrt32(f)}

	trunc = {f; -> trunc32(f)}
	floor = {f; -> floor32(f)}
	ceil  = {f; -> ceil32(f)}

	kahan_sum = {l; -> kahan_sum32(l) }
	priest_sum = {l; -> priest_sum32(l) }
;;

impl fpmath flt64 =
	fma = {x, y, z; -> fma64(x, y, z)}

	sqrt = {f; -> sqrt64(f)}

	trunc = {f; -> trunc64(f)}
	floor = {f; -> floor64(f)}
	ceil  = {f; -> ceil64(f)}

	kahan_sum = {l; -> kahan_sum64(l) }
	priest_sum = {l; -> priest_sum64(l) }
;;

extern const fma32 : (x : flt32, y : flt32, z : flt32 -> flt32)
extern const fma64 : (x : flt64, y : flt64, z : flt64 -> flt64)

extern const sqrt32 : (x : flt32 -> flt32)
extern const sqrt64 : (x : flt64 -> flt64)

extern const trunc32 : (f : flt32 -> flt32)
extern const trunc64 : (f : flt64 -> flt64)

extern const floor32 : (f : flt32 -> flt32)
extern const floor64 : (f : flt64 -> flt64)

extern const ceil32  : (f : flt32 -> flt32)
extern const ceil64  : (f : flt64 -> flt64)

extern const kahan_sum32 : (l : flt32[:] -> flt32)
extern const kahan_sum64 : (l : flt64[:] -> flt64)

extern const priest_sum32 : (l : flt32[:] -> flt32)
extern const priest_sum64 : (l : flt64[:] -> flt64)