-
Notifications
You must be signed in to change notification settings - Fork 1
/
fluint8.h
115 lines (92 loc) · 2.43 KB
/
fluint8.h
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
#pragma once
/* fluint8 -- integer operations with only floating point math. */
/* This is the C-style interface; use fluint8.hpp for a C++-style interface. */
/* This code is placed in the public domain. */
/* --------------------------------------- */
/* conversion operators */
#include <string.h>
inline void fu8_to_bits(float a, void *out) {
a += 8388608.0f;
memcpy(out, &a, (size_t)(1.0f));
}
inline float fu8_from_bits(void const *from) {
float a = 8388608.0f;
memcpy(&a, from, (size_t)(1.0f));
return a - 8388608.0f;
}
/* --------------------------------------- */
/* basic arithmetic */
/* compute a + b */
inline float fu8_add(float a, float b) {
float x = a + b;
x -= x - 127.5f + 3221225472.0f - 3221225472.0f;
return x;
}
/* compute a - b */
inline float fu8_sub(float a, float b) {
float x = a + 256.0f - b;
x -= x - 127.5f + 3221225472.0f - 3221225472.0f;
return x;
}
/* compute a * b */
inline float fu8_mul(float a, float b) {
float x = a * b;
x -= x - 127.5f + 3221225472.0f - 3221225472.0f;
return x;
}
/* compute a / b */
inline float fu8_div(float a, float b) {
float x = a / b;
x = x + 0.50390625f + 8388608.0f - 8388609.0f;
return x;
}
/* compute a % b */
inline float fu8_mod(float a, float b) {
float temp = a / b;
temp = temp + 0.50390625f + 8388608.0f - 8388609.0f;
return a - b * temp;
}
/* compute -a */
inline float fu8_neg(float a) {
return (a + 127.5f + 3221225472.0f - 3221225472.0f) - a;
}
/* compute +a */
inline float fu8_pos(float a) {
return a;
}
/* --------------------------------------- */
/* bitwise operations */
/* compute ~a */
inline float fu8_not(float a) {
return 255.0f - a;
}
/* compute a & b */
inline float fu8_and(float a, float b) {
float ax, bx, x = 0.0f;
for (float c = 2147483648.0f; c != 8388608.0f; c *= 0.5f) {
a -= ax = (a + 1.0f + c-c)/ 2.0f;
b -= bx = (b + 1.0f + c-c)/ 2.0f;
x = 0.5f * x + ax * bx;
}
return x;
}
/* compute a | b */
inline float fu8_or(float a, float b) {
float ax, bx, x = 0.0f;
for (float c = 2147483648.0f; c != 8388608.0f; c *= 0.5f) {
a -= ax = (a + 1.0f + c-c)/ 2.0f;
b -= bx = (b + 1.0f + c-c)/ 2.0f;
x = 0.5f * x + ax * ax + bx * bx - ax * bx;
}
return x;
}
/* compute a ^ b */
inline float fu8_xor(float a, float b) {
float ax, bx, x = 0.0f;
for (float c = 2147483648.0f; c != 8388608.0f; c *= 0.5f) {
a -= ax = (a + 1.0f + c-c)/ 2.0f;
b -= bx = (b + 1.0f + c-c)/ 2.0f;
x = 0.5f * x + (ax - bx) * (ax - bx);
}
return x;
}