Averages/Simple moving average: Difference between revisions

Content deleted Content added
→‎{{header|D}}: Change to handle Intergral input, while output keep floating
Line 266:
return 0;
}</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}}==