-
Notifications
You must be signed in to change notification settings - Fork 2
/
mathfuncs.ino
105 lines (89 loc) · 2.28 KB
/
mathfuncs.ino
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
//the standard 64 bit math brings in 5000+ bytes
//these bring in 1214 bytes, and everything is pass by reference
void init64(unsigned long an[], unsigned long bigPart, unsigned long littlePart ){
an[0]=bigPart;
an[1]=littlePart;
}
//left shift 64 bit "number"
void shl64(unsigned long an[]){
an[0] <<= 1;
if(an[1] & 0x80000000)
an[0]++;
an[1] <<= 1;
}
//right shift 64 bit "number"
void shr64(unsigned long an[]){
an[1] >>= 1;
if(an[0] & 0x1)
an[1]+=0x80000000;
an[0] >>= 1;
}
//add ann to an
void add64(unsigned long an[], unsigned long ann[]){
an[0]+=ann[0];
if(an[1] + ann[1] < ann[1])
an[0]++;
an[1]+=ann[1];
}
//subtract ann from an
void sub64(unsigned long an[], unsigned long ann[]){
an[0]-=ann[0];
if(an[1] < ann[1]){
an[0]--;
}
an[1]-= ann[1];
}
//true if an == ann
bool eq64(unsigned long an[], unsigned long ann[]){
return (an[0]==ann[0]) && (an[1]==ann[1]);
}
//true if an < ann
bool lt64(unsigned long an[], unsigned long ann[]){
if(an[0]>ann[0]) return false;
return (an[0]<ann[0]) || (an[1]<ann[1]);
}
//divide num by den
void div64(unsigned long num[], unsigned long den[]){
unsigned long zero64[]={0,0};
unsigned long quot[2];
unsigned long qbit[2];
unsigned long tmp[2];
init64(quot,0,0);
init64(qbit,0,1);
if (eq64(num, zero64)) { //numerator 0, call it 0
init64(num,0,0);
return;
}
if (eq64(den, zero64)) { //numerator not zero, denominator 0, infinity in my book.
init64(num,0xffffffff,0xffffffff);
return;
}
init64(tmp,0x80000000,0);
while(lt64(den,tmp)){
shl64(den);
shl64(qbit);
}
while(!eq64(qbit,zero64)){
if(lt64(den,num) || eq64(den,num)){
sub64(num,den);
add64(quot,qbit);
}
shr64(den);
shr64(qbit);
}
//remainder now in num, but using it to return quotient for now
init64(num,quot[0],quot[1]);
}
//multiply num by den
void mul64(unsigned long an[], unsigned long ann[]){
unsigned long p[2] = {0,0};
unsigned long y[2] = {ann[0], ann[1]};
unsigned long zero64[]={0,0};
while(!eq64(y,zero64)) {
if(y[1] & 1)
add64(p,an);
shl64(an);
shr64(y);
}
init64(an,p[0],p[1]);
}