You are here:

C++/C++ Data types

Advertisement


Question
Okay that's great! But where is the other part of the answer?

How can I fix this?

-------------------------
Followup To
Question -
Basically, I created a simple C++ class (I provided below) that would print some mathematical values such as the ‘mean' of some given data or calculating the ‘range', ‘midrange' or ‘median'.

I created a generic version of my class (also provided below), and found double to be a very good type to work with, but then I encountered the following problem:

Using double type, when I enter data: 1.7   1.7, I get the expectable answer which is;
Min. Value = 1.7
Max. Value = 1.7
Range Value = 0
Midrange Value = 1.7
Median Value = 1.7
Mean Value = 1.7
Variance Value  = 0
Std. Deviation = 0

But then the problem starts when I enter larger data like
1.7976931348623158e+308
1.7976931348623158e+308
I get strange answers:
Min. Value = 1.79769e+308 “Strange! Where is the rest of the number?”
Max. Value = 1.79769e+308
Range Value = 0
Midrange Value = 1.79769e+308
Median Value = 1.79769e+308
Mean Value = Infinity “What does this mean?”
Variance Value  = Infinity
Std. Deviation = Infinity

Can you tell where the problem is? Or how can I fix this so it accepts large values just like the one provided above.



#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <math.h>

using namespace std;

class sample {
  
  vector<double> vec_elements;//data vector of the sample
  
  public:
  sample() {}
  sample(vector<double> v):vec_elements(v){}
  
  /*Returns the size of the sample.*/
  int get_size() const {
     return vec_elements.size();
  }
  
  /*Sorts the data vector of the sample.*/
  void sort_data() {
     sort(vec_elements.begin(), vec_elements.end());
  }

  /*Allowing accessing to values within a vector represented by sample.*/
  double & operator[](int index) const {//i.e. now u can use 'smpl[i]'
     vec_elements.operator[](index);
  }

  /*Add doubles to the sample.*/
  void push(const double &x) {vec_elements.push_back(x);}


  /*Returns the data vector of the sample.*/
  const vector<double> &get_data() {
     return vec_elements;      
  }
  

  /*Takes a vector, and copy its contents to the data vector of the sample.*/
  void set_data(const vector<double> &v) {
     for (int i = 0; i < v.size(); i++) {
        vec_elements.push_back(v[i]);
     }
  }


  /*Retrieves the minimum value of the data in the sample.*/
  double minimum() {
     sort_data();
     double minimum_value = vec_elements.front();      
     return minimum_value;
  }

  /*Retrieves the maximum value of the data in the sample.*/
  double maximum() {
     sort_data();
     double maximum_value = vec_elements.back();
     return maximum_value;      
  }


  /*Retrieves the range of the data in the sample.*/
  double range() {
     sort_data();
     double minimum_value = vec_elements.front();   
     double maximum_value = vec_elements.back();
     return (maximum_value - minimum_value);      
  }

  /*Retrieves the mid range of the data in the sample.*/
  double midrange() {
     double minimum_value = vec_elements.front();   
     double maximum_value = vec_elements.back();
     double midrange = (maximum_value + minimum_value)/2;
     return midrange;
  }
  
  /*Sums all the data in the vector.*/
  double sum() {
     double sum = 0;
     for (int i = 0; i < vec_elements.size(); i++) {
        sum = sum + vec_elements[i];   
     }
     return sum;
  }

  /*A method that returns the mean of the data in the sample.*/
  double mean() {      
     double mean = sum()/vec_elements.size();      
     return mean;      
  }

  /*Squares the numbers.*/
  double square(double i) { return i*i; }

  /*Calculates the variance of the data sample.*/
  double variance() {
     double the_mean = mean();
     double square_of_subtraction = 0;
     double sum_of_square = 0;
     double the_variance;
     int sample_size = vec_elements.size();

     for (int i = 0; i < sample_size; i++) {
        square_of_subtraction = square(vec_elements[i] - the_mean);         
        sum_of_square = sum_of_square + square_of_subtraction;         
     }   
     the_variance = sum_of_square/sample_size;
     return the_variance;      
  }


  /*Calculates the Standard deviation of the data sample.*/
  double std_deviation() {
     double deviation = sqrt(variance());
     return deviation;      
  }

  /*Calculates the median of the data sample.*/
  double median() {
     sort_data();//sort the vector first
     int sample_size = vec_elements.size();
     double median;
     double middle_position_one;
     double middle_position_two;
         
     if ((sample_size % 2) == 0){//even
        middle_position_one = (sample_size /2);
        middle_position_two = (sample_size /2)+1;
        median = (vec_elements[middle_position_one-1] + vec_elements[middle_position_two-1])/2;
     } else
        if ((sample_size % 2) != 0) {//odd
         middle_position_one = (sample_size /2)+1;
         median = vec_elements[middle_position_one-1];

     }
     return median;
  }


};



/*Define the output operator*/
ostream& operator<<(ostream &s, const sample & smpl) {
  s << '<' << smpl.get_size() << ':' << ' ';
  for (int i = 0; i < smpl.get_size(); i++) {
     s << smpl[i] << ' ';
  }   
  s  << '>';
  return s;
}



/*Define the operator input.*/
istream& operator>>(istream &s, sample & smpl) {
  vector<double> vec;
  char left_tag, dots, right_tag;
  int size;
  double number;
  if (s >> left_tag) {   
     if ((s >> size >> dots) && (left_tag == '<' && dots == ':')) {  
        int i = 0;
        while (i < size) {
         s >> number;
         vec.push_back(number);          
         i++;
        }
        if ((s >> right_tag) && (right_tag == '>')) {
         smpl = sample(vec);
        } else {s.setstate(ios::badbit);//read faild
        cout << "Please ensure the data entered is correct!" << '\n';}
     } else s.setstate(ios::badbit);//read faild          
  }
  return s;
}





#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <math.h>

using namespace std;

/*Generic version of sample class*/
template <typename Item> class samplet {
  
  vector<Item> vec_elements;//data vector of the samplet
  typedef vector<double>::iterator iter;
  
  public:
  samplet() {}
  samplet(vector<Item> v):vec_elements(v){}
  
  /*Returns the size of the samplet.*/
  int get_size() const {
     return vec_elements.size();
  }
  
  /*Sorts the data vector of the samplet.*/
  void sort_data() {
     iter first_element = vec_elements.begin();
     iter last_element = vec_elements.end();
     sort(first_element, last_element);
  }

  /*Allowing accessing to values within a vector represented by samplet.*/
  Item & operator[](int index) const {//i.e. now u can use 'smpl[i]'
     vec_elements.operator[](index);
  }

  /*Add to the samplet.*/
  void push(const Item &x) {vec_elements.push_back(x);}


  /*Returns the data vector of the samplet.*/
  const vector<Item> &get_data() {
     return vec_elements;      
  }
  

  /*Takes a vector, and copy its contents to the data vector of the samplet.*/
  void set_data(const vector<Item> &v) {
     for (vector<Item>::const_iterator it  = v.begin(); it != v.end(); ++it) {
        vec_elements.push_back(*it);
     }
  }


  /*Retrieves the minimum value of the data in the samplet.*/
  Item minimum() {
     sort_data();
     iter minimum_value = vec_elements.begin();      
     return *minimum_value;
  }

  /*Retrieves the maximum value of the data in the samplet.*/
  Item maximum() {
     sort_data();
     iter maximum_value = vec_elements.end()-1;
     return *maximum_value;      
  }


  /*Retrieves the range of the data in the samplet.*/
  Item range() {
     sort_data();
     iter minimum_value = vec_elements.begin();   
     iter maximum_value = vec_elements.end()-1;
     return (*maximum_value - *minimum_value);
  }

  /*Retrieves the mid range of the data in the samplet.*/
  Item midrange() {
     iter minimum_value = vec_elements.begin();   
     iter maximum_value = vec_elements.end()-1;
     Item midrange = (*maximum_value + *minimum_value)/2;
     return midrange;
  }
  
  /*Sums all the data in the vector.*/
  Item sum() {
     Item sum = 0;
     for (iter i  = vec_elements.begin(); i != vec_elements.end(); ++i) {         
        sum = sum + vec_elements[*i];
     }      
     return sum;
  }

  /*A method that returns the mean of the data in the samplet.*/
  Item mean() {      
     Item mean = sum()/vec_elements.size();      
     return mean;      
  }

  /*Squares the numbers.*/
  Item square(Item i) { return i*i; }

  /*Calculates the variance of the data samplet.*/
  Item variance() {
     Item the_mean = mean();
     Item square_of_subtraction = 0;
     Item sum_of_square = 0;
     Item the_variance;
     int samplet_size = vec_elements.size();

     for (int i = 0; i < samplet_size; i++) {
        square_of_subtraction = square(vec_elements[i] - the_mean);         
        sum_of_square = sum_of_square + square_of_subtraction;         
     }   
     the_variance = sum_of_square/samplet_size;
     return the_variance;      
  }


  /*Calculates the Standard deviation of the data samplet.*/
  Item std_deviation() {
     Item deviation = sqrt(variance());
     return deviation;      
  }

  /*Calculates the median of the data samplet.*/
  Item median() {
     sort_data();//sort the vector first
     int samplet_size = vec_elements.size();
     Item median;
     Item middle_position_one;
     Item middle_position_two;
         
     if ((samplet_size % 2) == 0){//even
        middle_position_one = (samplet_size /2);
        middle_position_two = (samplet_size /2)+1;
        median = (vec_elements[middle_position_one-1] + vec_elements[middle_position_two-1])/2;
     } else
        if ((samplet_size % 2) != 0) {//odd
         middle_position_one = (samplet_size /2)+1;
         median = vec_elements[middle_position_one-1];

     }
     return median;
  }

};



/*Define the output operator*/
template <typename Item>
ostream& operator<<(ostream &s, const samplet<Item> & smpl) {
  s << '<' << smpl.get_size() << ':' << ' ';
  for (int i = 0; i < smpl.get_size(); i++) {
     s << smpl[i] << ' ';
  }   
  s  << '>';
  return s;
}



/*Define the operator input.*/
template <typename Item>
istream& operator>>(istream &s, samplet<Item> & smpl) {
  vector<Item> vec;
  char left_tag, dots, right_tag;
  int size;
  Item number;
  if (s >> left_tag) {   
     if ((s >> size >> dots) && (left_tag == '<' && dots == ':')) {  
        int i = 0;
        while (i < size) {
         s >> number;
         vec.push_back(number);          
         i++;
        }
        if ((s >> right_tag) && (right_tag == '>')) {
         smpl = samplet<Item>(vec);
        } else {s.setstate(ios::badbit);//read faild
        cout << "Please ensure the data entered is correct!" << '\n';}
     } else s.setstate(ios::badbit);//read faild          
  }
  return s;
}





#include <iostream>
#include "sample.h"

using namespace std;

int main (void) {
  sample s;
  while (cin >> s)
  cout << s.minimum() << endl << s.maximum() << endl
      << s.range() << endl << s.midrange() << endl
      << s.median() << endl << s.mean() << endl
      << s.variance() << endl << s.std_deviation() << endl;

  if (cin.bad())
     cerr << "\nBad input\n\n";

  return(0);
}

Answer -
This is quite normal. Double type uses limited amount of memory to keep data. So it only stores the most important part of a real number. About the limitations of double, you can see the help file of your compiler, because the limitation varies from compiler to compiler.

Answer
You can fix this problem by specifying the precision you expect. double variable type is limited, if you want to go beyond that, you need to use other types. Some compilers give larger variable types. Also sometimes you can save your real number in Interger format. There are some large intereger variable types implemented by third parties. You don't need to send me your program. For helping with writing programs, you may email programming@shabah.net, but if you want to know what type you can use, please precisely let me know the format of the numbers you have and the operations that you want to do on them. Note that some real numbers cannot be exact in C++ programming. For instance, numbers like Pi and e are endless and you should cut them from somewhere. I need to know from where you want to cut your real numbers.

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Sam

Expertise

You may ask me about simple to complicated C/C++ programming methods/style and most like questions about network programming in C++.

Experience

I'm a professional programer in C++ and network/internet programming.

©2016 About.com. All rights reserved.