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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
#include <gc.h>
#include <gc/cord.h>
#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "../SipHash/halfsiphash.h"
#include "array.h"
#include "nums.h"
#include "string.h"
#include "types.h"
public CORD Num__as_text(const double *f, bool colorize, const TypeInfo *type) {
(void)type;
if (!f) return "Num";
CORD c;
if (colorize) CORD_sprintf(&c, "\x1b[35m%g\x1b[33;2m\x1b[m", *f);
else CORD_sprintf(&c, "%g", *f);
return c;
}
public int32_t Num__compare(const double *x, const double *y, const TypeInfo *type) {
(void)type;
return (*x > *y) - (*x < *y);
}
public bool Num__equal(const double *x, const double *y, const TypeInfo *type) {
(void)type;
return *x == *y;
}
public bool Num__near(double a, double b, double ratio, double absolute) {
if (ratio < 0) ratio = 0;
else if (ratio > 0) ratio = 1;
if (a == b) return true;
double diff = fabs(a - b);
if (diff < absolute) return true;
else if (isnan(diff)) return false;
double epsilon = fabs(a * ratio) + fabs(b * ratio);
if (isinf(epsilon)) epsilon = DBL_MAX;
return (diff < epsilon);
}
public CORD Num__format(double f, int64_t precision) {
return CORD_asprintf("%.*f", (int)precision, f);
}
public CORD Num__scientific(double f, int64_t precision) {
return CORD_asprintf("%.*e", (int)precision, f);
}
public double Num__mod(double num, double modulus) {
double result = fmod(num, modulus);
return (result < 0) != (modulus < 0) ? result + modulus : result;
}
public double Num__random(void) {
return drand48();
}
public double Num__nan(CORD tag) {
return nan(CORD_to_const_char_star(tag));
}
public bool Num__isinf(double n) { return !!isinf(n); }
public bool Num__finite(double n) { return !!finite(n); }
public bool Num__isnan(double n) { return !!isnan(n); }
public const TypeInfo Num = {
.size=sizeof(double),
.align=__alignof__(double),
.tag=CustomInfo,
.CustomInfo={
.compare=(void*)Num__compare,
.equal=(void*)Num__equal,
.as_text=(void*)Num__as_text,
},
};
public CORD Num32__as_text(const float *f, bool colorize, const TypeInfo *type) {
(void)type;
if (!f) return "Num32";
CORD c;
if (colorize) CORD_sprintf(&c, "\x1b[35m%g_f32\x1b[m", *f);
else CORD_sprintf(&c, "%g_f32", *f);
return c;
}
public int32_t Num32__compare(const float *x, const float *y, const TypeInfo *type) {
(void)type;
return (*x > *y) - (*x < *y);
}
public bool Num32__equal(const float *x, const float *y, const TypeInfo *type) {
(void)type;
return *x == *y;
}
public bool Num32__near(float a, float b, float ratio, float absolute) {
if (ratio < 0) ratio = 0;
else if (ratio > 0) ratio = 1;
if (a == b) return true;
float diff = fabs(a - b);
if (diff < absolute) return true;
else if (isnan(diff)) return false;
float epsilon = fabs(a * ratio) + fabs(b * ratio);
if (isinf(epsilon)) epsilon = FLT_MAX;
return (diff < epsilon);
}
public CORD Num32__format(float f, int64_t precision) {
return CORD_asprintf("%.*f", (int)precision, f);
}
public CORD Num32__scientific(float f, int64_t precision) {
return CORD_asprintf("%.*e", (int)precision, f);
}
public float Num32__mod(float num, float modulus) {
float result = fmodf(num, modulus);
return (result < 0) != (modulus < 0) ? result + modulus : result;
}
public float Num32__random(void) {
return (float)drand48();
}
public float Num32__nan(CORD tag) {
return nanf(CORD_to_const_char_star(tag));
}
public bool Num32__isinf(float n) { return isinf(n); }
public bool Num32__finite(float n) { return finite(n); }
public bool Num32__isnan(float n) { return isnan(n); }
public const TypeInfo Num32 = {
.size=sizeof(float),
.align=__alignof__(float),
.tag=CustomInfo,
.CustomInfo={
.compare=(void*)Num32__compare,
.equal=(void*)Num32__equal,
.as_text=(void*)Num32__as_text,
},
};
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|