-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathch02.h
More file actions
113 lines (99 loc) · 2.59 KB
/
ch02.h
File metadata and controls
113 lines (99 loc) · 2.59 KB
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
// Copyright (c) 2014 Alexander A. Stepanov and Daniel E. Rose
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without
// fee, provided that the above copyright notice appear in all copies
// and that both that copyright notice and this permission notice
// appear in supporting documentation. The authors make no
// representations about the suitability of this software for any
// purpose. It is provided "as is" without express or implied
// warranty.
//
// This code accompanies the "fM2GP" book:
//
// From Mathematics to Generic Programming
// by Alexander Stepanov and Daniel E. Rose
// Addison-Wesley Professional, 2015
//
// -------------------------------------------------------------------
// ch02.h -- Functions from Chapter 2 of fM2GP.
// -------------------------------------------------------------------
// Section 2.1
bool odd(int n) { return n & 0x1; }
int half(int n) { return n >> 1; }
int multiply0(int n, int a) {
if (n == 1) return a;
return multiply0(n - 1, a) + a;
}
int multiply1(int n, int a) {
if (n == 1) return a;
int result = multiply1(half(n), a + a);
if (odd(n)) result = result + a;
return result;
}
int multiply_by_15(int a) {
int b = (a + a) + a;
int c = b + b;
return (c + c) + b;
}
// Section 2.2
int mult_acc0(int r, int n, int a) {
if (n == 1) return r + a;
if (odd(n)) {
return mult_acc0(r + a, half(n), a + a);
} else {
return mult_acc0(r, half(n), a + a);
}
}
int mult_acc1(int r, int n, int a) {
if (n == 1) return r + a;
if (odd(n)) r = r + a;
return mult_acc1(r, half(n), a + a);
}
int mult_acc2(int r, int n, int a) {
if (odd(n)) {
r = r + a;
if (n == 1) return r;
}
return mult_acc2(r, half(n), a + a);
}
int mult_acc3(int r, int n, int a) {
if (odd(n)) {
r = r + a;
if (n == 1) return r;
}
n = half(n);
a = a + a;
return mult_acc3(r, n, a);
}
int mult_acc4(int r, int n, int a) {
while (true) {
if (odd(n)) {
r = r + a;
if (n == 1) return r;
}
n = half(n);
a = a + a;
}
}
int multiply2(int n, int a) {
if (n == 1) return a;
return mult_acc4(a, n - 1, a);
}
int multiply3(int n, int a) {
while (!odd(n)) {
a = a + a;
n = half(n);
}
if (n == 1) return a;
return mult_acc4(a, n - 1, a);
}
int multiply4(int n, int a) {
while (!odd(n)) {
a = a + a;
n = half(n);
}
if (n == 1) return a;
// even(n - 1) => n - 1 != 1
return mult_acc4(a, half(n - 1), a + a);
}