I've attached a shell script that reproduces the problem.

#!/bin/sh
##
## Create BaseClass.hpp
##
cat >BaseClass.hpp <<END_BaseClass.hpp
#ifndef BASE_CLASS_HPP
#define BASE_CLASS_HPP

#include <stddef.h>
#include <math.h>

class BaseClass
{
  public:
  
    enum AveragingMethod
    {
       NONE,
       LINEAR,
       RMS,
       HMS,
       MINIMUM,
       MAXIMUM,
       HARMONIC,
       GEOMETRIC,
       SUM,
       SUM_SQUARED,
       STANDARD_DEVIATION,
       MAX_OVER_MIN,
       MAX_MINUS_MIN,
    };
  
    BaseClass( AveragingMethod method ) : avgMethod(method) {}

    virtual double get_value( ) = 0;
    
    
    void set_averaging_method( AveragingMethod method ) { avgMethod = method; }
    AveragingMethod get_averaging_method() const { return avgMethod; }

  protected:
  
    inline double average_values( double list[], size_t len );
    
  private:
  
    AveragingMethod avgMethod;
};

inline double BaseClass::average_values( double list[], size_t len )
{
  size_t i;
  double result = 0, other = 0;
  
  switch (avgMethod) {
    default:
      break;
    case LINEAR:
      for (i = 0; i < len; ++i)
        result += list[i];
      result /= len;
      break;
    case RMS:
      for (i = 0; i < len; ++i)
        result += list[i] * list[i];
      result = sqrt(result/len);
      break;
    case HMS:
      for (i = 0; i < len; ++i) 
        result += 1.0 / (list[i] * list[i]);
      result = sqrt( len / result );
      break;
    case MINIMUM:
      result = HUGE_VAL;
      for ( i = 0; i < len; ++i)
        if (list[i] < result)
          result = list[i];
      break;
    case MAXIMUM:
      result = -HUGE_VAL;
      for ( i = 0; i < len; ++i)
        if (list[i] > result)
          result = list[i];
      break;
    case HARMONIC:
      for (i = 0; i < len; ++i) 
        result += 1.0 / list[i];
      result = len / result;
      break;
    case GEOMETRIC:
      result = 1;
      for (i = 0; i < len; ++i)
        result *= list[i];
      result = pow( result, 1.0/len );
      break;
    case SUM:
      for (i = 0; i < len; ++i)
        result += list[i];
      break;
    case SUM_SQUARED:
      for (i = 0; i < len; ++i)
        result += list[i] * list[i];
      break;
    case STANDARD_DEVIATION:
      for (i = 0; i < len; ++i) {
        result += (list[i] * list[i]);
        other += list[i];
      }
      result = ((other * other) / (len * len)) - result / len;
      break;
    case MAX_OVER_MIN:
    case MAX_MINUS_MIN:
      result = -HUGE_VAL;
      other = HUGE_VAL;
      for (i = 0; i < len; ++i) {
        if (list[i] > result)
          result = list[i];
        if (list[i] < other)
          other = list[i];
      }
      if (avgMethod == MAX_OVER_MIN)
        result /= other;
      else
        result -= other;
      break;
  }
  
  return result;
}


#endif

END_BaseClass.hpp
##
## Create FileReader.hpp
##
cat >FileReader.hpp <<END_FileReader.hpp
#ifndef FILE_READER_HPP
#define FILE_READER_HPP

#include "BaseClass.hpp"
#include <string>

class FileReader : public BaseClass
{
  public:
  
    FileReader( std::string filename ) : BaseClass( LINEAR ), 
fileName(filename) {}
    
    virtual double get_value( );
    
  private:
    std::string fileName;
};

#endif

END_FileReader.hpp
##
## Create FileReader.cpp
##
cat >FileReader.cpp <<END_FileReader.cpp
#include "FileReader.hpp"
#include <stdio.h>
#include <vector>

double FileReader::get_value()
{
  std::vector<double> list;
  double d;
  FILE* file = fopen( fileName.c_str(), "r" );
  if (!file)
    return 0;
  while (fscanf( file, "%lf", &d ) == 1)
    list.push_back(d);
  
  return average_values( &list[0], list.size() );
}

END_FileReader.cpp
##
## Create Random.hpp
##
cat >Random.hpp <<END_Random.hpp
#ifndef RANDOM_HPP
#define RANDOM_HPP

#include "BaseClass.hpp"

class Random : public BaseClass
{
  public:
  
    Random( unsigned count ) : BaseClass( RMS ), numValues(count) {}
    
    virtual double get_value( );
    
  private:
    unsigned numValues;
};

#endif

END_Random.hpp
##
## Create Random.cpp
##
cat >Random.cpp <<END_Random.cpp
#include "Random.hpp"
#include <vector>
#include <stdlib.h>

double Random::get_value()
{
  std::vector<double> list( numValues );
  for (std::vector<double>::iterator i = list.begin(); i != list.end(); ++i)
    *i = rand();
  return average_values( &list[0], list.size() );
}

END_Random.cpp
##
## Create main.cpp
##
cat >main.cpp <<END_main.cpp
#include "FileReader.hpp"
#include "Random.hpp"

int main( int argc, char* argv[] )
{
  Random r( 100 );
  printf( "<random>: %f\n", r.get_value() );
  for (int i = 1; i < argc; ++i)
  {
    FileReader f( argv[i] );
    printf("%s: %f\n", argv[i], f.get_value());
  }
  return 0;
}

END_main.cpp
##
## Create Makefile
##
cat >Makefile <<END_Makefile
OBJS = FileReader.o Random.o main.o
CXX = g++-3.3

main: \$(OBJS)
        \$(CXX) -o \$@ \$?

END_Makefile
##
## Compile and link
##
make

Reply via email to