-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathficx.h
93 lines (77 loc) · 1.61 KB
/
ficx.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
#include <stdlib.h>
#include <inttypes.h>
#include <stdio.h>
//fixed point arithmetic library
typedef int16_t fixed; //choose your width, and specify the double width type
typedef int32_t dfixed;
#define bpoint 9 //binary point places
#define SWAP(a, b) (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b)))
//multiply and divide
#define fmul(x, y) ((fixed)((dfixed)x*(dfixed)y>>bpoint)) //a/x*b/x in terms of x: (ab/x)/x
#define fdiv(x, y) ((fixed)(((dfixed)x<<bpoint)/(dfixed)y)) //a/x / b/x in terms of x: (ax/b)/x
//convert number to fixed point
#define fix(x) ((fixed)x<<bpoint)
//output routines
#define whole(x) (x>>bpoint)
#define pointmask ((1<<bpoint)-1)
#define frac(x) (x&pointmask)
char buf[15];
fixed fxsqrt(fixed n) {
if(n < 0) {
return fix(-1);
}
if(n == 0) {
return 0;
}
fixed x = n >> 1;
fixed y = 0;
for(;;) {
y = (x + fdiv(n,x)) >> 1;
if( y >= x) {
return x;// << (bpoint >> 1);
}
x = y;
}
}
//output first the whole number, then the point, and then the fractional point
char *fxtoa(fixed f, char *out){
div_t d;
char *res = out;
char *head = out-1;
uint8_t j = 0;
if(f < 0 && !*out) {
*(out++) = '-';
f = ~f + 1;
head++;
}
fixed i = whole(f);
if(*out == -1) {
return res;
}
do {
d = div(i, 10);
*(out++) = d.rem + '0';
i = d.quot;
j++;
} while(d.quot != 0 && ~*out);
char *foot = out;
j /= 2;
while (j) {
char c = head[j];
head[j] = foot[-j];
foot[-j] = c;
j--;
}
*(out++) = '.';
if(*out == -1) {
return res;
}
f = frac(f) * 10;
do {
i = whole(f);
*(out++) = i + '0';
f = frac(f) * 10;
} while(f != 0 && ~*out);
*out = '\0';
return res;
}