c++ - Output is either 6.9531e-308 or 0 (noob) -


i'm trying write program give cost of phone call based on when starts/ends , how long takes. works fine, except when tries display cost of each call , total cost @ end.

every cost listed $6.9531e-308. similar issue resolved issue initializing variable in question 0 when program starts listing every cost $0.

the way i'm calculating total doesn't seem working either, since when cost $6.9531e-308, total comes out $7.64841e-307 instead of $4.17186e-307. it's either multiplying 1 of costs 11 or thinks there's 11 costs need added up.

here code:

#include <fstream> #include <sstream> #include <iostream> #include <iomanip> #include <string> #include <cstring>  using namespace std;  ifstream fin("call_history.txt"); //read file  //int main int main() {      string temp;     double total = 0.0;      while (getline(fin, temp)) {         istringstream s(temp);         string token[3];         int = 0;          while(getline(s, token[i], ' ')) { //split string spaces , store token[0], token[1], etc.             i++;         }         //token[0] stores day of week         //token[1] stores time (i.e "14:32")         //token[2] stores duration          istringstream s2(token[1]);         string time_values[2];         = 0;          while(getline(s2, time_values[i], ':')) { //split token[1] ':'             i++;         }         //time_values[0] stores hour         //time_values[1] stores minute          //rename variables readibility         string day = token[0];         int hr = atoi(time_values[0].c_str()); //atoi convert string integer          int minute = atoi(time_values[1].c_str());         int duration = atoi(token[2].c_str());         double cost=0; //accumulator         int start_time = (hr*60)+minute;         int end_time = start_time+duration;         int startzone, endzone;          if (day == "mo" || day == "tu" || day == "we" || day == "th")             {                 day == "weekday";             }             if (day == "sa" || day == "su")             {                 day == "weekend";             }     //assigning each starting time zone             if ((day == "weekday" || day == "fr") && (start_time >= 480 && start_time < 1080))             {                 startzone = 1; //call starts on hours             }             if ((day == "weekday" || day == "fr") && (start_time <= 480))             {                 startzone = 2; //call starts before 8             }             if ((day == "weekday" || day == "fr") && (start_time >= 1080))             {                 startzone = 3; //call starts after 6 pm             }             if (day == "weekend")             {                 startzone = 4; //call starts on weekend             }     //assigning each ending time zone     //this program handle @ 3 zone changes in 1 call.              if (day == "weekday" && (end_time >= 480 && end_time <= 1080))             {                 endzone = 1; //call ends on-hours same day             }             if (day == "weekday" && (end_time >= 1080 && end_time <= 1920))             {                 endzone = 2; //call ends after 6 pm on same day, before 8 on next day             }             if (day == "weekday" && (end_time > 1920 && end_time <= 2520))             {                 endzone = 3; //call ends on-hours on next day             }             if (day == "weekday" && (end_time > 2520))             {                 endzone = 4; //call ends after 6 pm next day             }             if (day == "weekend" && (end_time <= 2880))             {                 endzone = 5; //call starts , ends on weekend             }             if (day == "fr" && (end_time >= 1440 && end_time <= 2880))             {                 endzone = 6; //call goes weekday weekend             }             if (day == "su" && (end_time >= 1440 && end_time <= 1920))             {                 endzone = 7; //call goes weekend weekday off-hours             }          //cost calculations         //call starts on hours                 if (startzone == 1 && endzone == 1) //call entirely within on-hours                 {                     cost = duration*0.4;                 }                 if (startzone == 1 && endzone == 2) //call starts on-hours , ends before 8 next day                 {                     cost = ((1080-start_time)*0.4) + ((end_time-1080)*0.25);                 }                 if (startzone == 1 && endzone == 3) //call starts on-hours , ends on-hours next day                 {                     cost = ((1080-start_time)*0.4) + (840*0.25) + ((end_time-1920)*0.4);                 }                 if (startzone == 1 && endzone == 4) //call starts on-hours , ends after 6 pm next day                 {                     cost = ((1080-start_time)*0.4) + (840*0.25) + (600*0.4) + ((end_time-2520)*0.25);                 }                 if ((startzone == 1 && endzone == 6)) //call starts on hours friday , ends on weekend                 {                     cost = ((1080-start_time)*0.4) + ((360)*0.25) + ((end_time-1440)*0.15);                 }          //call starts off hours                 if (startzone == 2 && endzone == 2) //call starts before 8 , ends before 8 next day                 {                     cost = ((480-start_time)*0.25) + (600*0.4) + ((end_time-1440)*0.25);                 }                 if (startzone == 2 && endzone == 3) //call starts before 8 , ends on-hours next day                 {                     cost = ((480-start_time)*0.25) + ((end_time-1920)*0.25);                 }                 if (startzone == 2 && endzone == 6) //call starts before 8 friday , ends on weekend                 {                     cost = ((480 - start_time)*0.25) + (600*0.4) + (360*0.25) + ((end_time-1440)*0.15);                 }                 if (startzone == 3 && endzone ==6) //call starts after 6 pm friday , ends on weekend                 {                     cost = ((1440-start_time)*0.25) + ((end_time-1440)*0.15);                 }                 if ((startzone == 3 && endzone == 2) || (startzone == 2 && end_time <= 480)) //call entirely within off-hours                 {                     cost = duration*0.25;                 }                 if ((startzone == 3 && endzone == 3)) //call starts after 6 pm , ends on-hours next day                 {                     cost = ((1920-start_time)*0.25) + ((end_time-1920)*0.4);                 }                 if ((startzone == 3 && endzone == 4)) //call starts after 6 pm , ends after 6 pm next day                 {                     cost = ((1920-start_time)*0.25) + (600*0.4) + ((end_time-2520)*0.25);                 }          //call starts on weekend                 if (startzone == 4 && endzone == 5) //call entirely within weekends                 {                     cost = duration*0.15;                 }                 if (startzone == 4 && endzone == 7) //call starts on sunday , ends before 8 monday                 {                     cost = ((1440-start_time)*0.15) + ((end_time-1440)*0.25);                 }          cout << setw(4)<< endl;         cout << day << " " << hr << ":" << minute << " " << duration << " $" << cost << "\n";         total += cost;      }     cout << setw(4) << endl;     cout << "\ttotal $" << total << "\n";  } 

the problem isn't (entirely) formulae, inherent limitations of floating point numbers

the key issue here between 2 numbers, there infinite number of real numbers (an uncountably infinite number of them, in fact), , finite amount of space in double represent them. there will rounding errors.

furthermore, since they're stored in base 2, not base 10, there exist numbers seem should representable, aren't. standard example being 0.1; there no finite representation of in base 2.

consider following:

#include <cstdio> int main() {     double x = 0.0;     (int = 0; < 10; i++) {         x += 0.1;         printf("%.20f\n", x);     } } 

this output following:

0.10000000000000000555 0.20000000000000001110 0.30000000000000004441 0.40000000000000002220 0.50000000000000000000 0.59999999999999997780 0.69999999999999995559 0.79999999999999993339 0.89999999999999991118 0.99999999999999988898 

now, last number should 1.0, is representable, point, rounding errors have added up, different. that's what's happening in code. there tiny rounding errors add 6.9531e-308, when value have been 0 if no rounding had happened. easiest solution print in format forces round final answer off point it's accurate. instance, if change printf("%.20f\n") printf("%.1f\n") in above example, print numbers expect. , in example, forcing not use scientific notation sufficient make round 0.

double x = 6.9531e-308; printf("%e\n", x); printf("%f\n", x); std::cout << x << "\n"; std::cout << std::fixed << x << "\n"; 

will output:

6.953100e-308 0.000000 6.9531e-308 0.000000 

if want understand gritty details of how floating point numbers work (which recommend if aren't @ stage of education yet), paper standard reference: what every computer scientist should know floating-point arithmetic

addendum:

also, day == "weekday"; mean day = "weekday"; in couple places, why it's near 0 @ all. more significant issue, albeit less interesting 1 talk about.


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -