Averages/Simple moving average: Difference between revisions
Content deleted Content added
→{{header|D}}: Change to handle Intergral input, while output keep floating |
|||
Line 266: | Line 266: | ||
return 0; |
return 0; |
||
}</lang> |
}</lang> |
||
=={{header|C++}}== |
|||
<lang C++> |
|||
#include <iostream> |
|||
using std::cout; |
|||
using std::endl; |
|||
class SMA { |
|||
public: |
|||
SMA(unsigned int period) : |
|||
period(period), window(new double[period]), head(NULL), tail(NULL), |
|||
total(0) { |
|||
assert(period >= 1); |
|||
} |
|||
~SMA() { |
|||
delete[] window; |
|||
} |
|||
// Adds a value to the average, pushing one out if nescessary |
|||
void add(double val) { |
|||
// Special case: Initialization |
|||
if (head == NULL) { |
|||
head = window; |
|||
*head = val; |
|||
tail = head; |
|||
inc(tail); |
|||
total = val; |
|||
return; |
|||
} |
|||
// Were we already full? |
|||
if (head == tail) { |
|||
// Fix total-cache |
|||
total -= *head; |
|||
// Make room |
|||
inc(head); |
|||
} |
|||
// Write the value in the next spot. |
|||
*tail = val; |
|||
inc(tail); |
|||
// Update our total-cache |
|||
total += val; |
|||
} |
|||
// Returns the average of the last P elements added to this SMA. |
|||
// If no elements have been added yet, returns 0.0 |
|||
double avg() const { |
|||
ptrdiff_t size = this->size(); |
|||
if (size == 0) { |
|||
return 0; // No entries => 0 average |
|||
} |
|||
return total / (double) size; // Cast to double for floating point arithmetic |
|||
} |
|||
private: |
|||
unsigned int period; |
|||
double * window; // Holds the values to calculate the average of. |
|||
// Logically, head is before tail |
|||
double * head; // Points at the oldest element we've stored. |
|||
double * tail; // Points at the newest element we've stored. |
|||
double total; // Cache the total so we don't sum everything each time. |
|||
// Bumps the given pointer up by one. |
|||
// Wraps to the start of the array if needed. |
|||
void inc(double * & p) { |
|||
if (++p >= window + period) { |
|||
p = window; |
|||
} |
|||
} |
|||
// Returns how many numbers we have stored. |
|||
ptrdiff_t size() const { |
|||
if (head == NULL) |
|||
return 0; |
|||
if (head == tail) |
|||
return period; |
|||
return tail - head; |
|||
} |
|||
}; |
|||
int main(int argc, char * * argv) { |
|||
SMA foo(3); |
|||
SMA bar(5); |
|||
int data[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 }; |
|||
for (int * itr = data; itr < data + 10; itr++) { |
|||
foo.add(*itr); |
|||
cout << "Added " << *itr << " avg: " << foo.avg() << endl; |
|||
} |
|||
cout << endl; |
|||
for (int * itr = data; itr < data + 10; itr++) { |
|||
bar.add(*itr); |
|||
cout << "Added " << *itr << " avg: " << bar.avg() << endl; |
|||
} |
|||
return 0; |
|||
} |
|||
</lang> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |