return from my function is nan

Discussion in 'C++' started by utab, Jan 28, 2007.

  1. utab

    utab Guest

    Dear all,

    I tried sth easy(actually this was an exercise) but I tried to use the
    standard lib. heavily for this problem(as far as I can). There was one
    point I could not figure out. The problem is :

    ../a.out 1.3+3.2+.1+40/3*8/7-4*5-32

    The program will parse the argument and find the result of the above
    expression. I have two versions(the 2nd is working , not perfect ;-}),
    but the first have a return problem I guess because if I use that
    version I get "nan" as the result at line 37. What is my problem?

    Sorry that there are some comments and cout statement in around the
    code. But I guess it could be easier to figure out.

    My Best,

    1: this version returns nan from the "performer function"
    --------------
    3 #include <iostream>
    4 #include <string>
    5 #include <vector>
    6 #include <sstream>
    7 #include <algorithm>
    8 #include <cstdlib>
    9 using namespace std;
    10
    11 template <typename T>
    12 T str_To_num (const std::string & s)
    13 {
    14 T result;
    15 std::istringstream stream (s);
    16 if (stream >> result)
    17 return result;
    18 else{
    19 cerr << "error in conversion" <<endl;
    20 return EXIT_FAILURE;
    21 }
    22 }
    23 void parse_string(const
    string&str,vector<double>&string_num_vec,vector<char>&operators_vec){
    24 string str_temp=str;
    25 string operators("+-*/");
    26 string value;
    27 string::size_type index;
    28 while((index=str_temp.find_first_of(operators))!
    =string::npos){
    29 operators_vec.push_back(str_temp[index]);
    30 value=str_temp.substr(0,index);
    31
    string_num_vec.push_back(str_To_num<double>(value));
    32 str_temp=str_temp.substr(index+1);
    33
    if(str_temp.find_first_of(operators)==string::npos)
    34
    string_num_vec.push_back(str_To_num<double>(str_temp));
    35 }
    36 }
    37 double performer(vector<double>&vec_d,vector<char>&vec_ch){
    38 double result_temp;
    39 string md("*/");
    40 string pm("+-");
    41 vector<char>::iterator iter;
    42 vector<int>::size_type index;
    43
    if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
    )!=vec_ch.end())
    44 ;
    45 else
    if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),pm.begin(),pm.end())
    )!=vec_ch.end())
    46 ;
    47 else
    48 ;
    49 switch (*iter){
    50 case '*':
    51 index = iter-vec_ch.begin();
    52 result_temp=vec_d[index]*vec_d[index+1];
    53
    vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    +index)),result_temp);
    54 vec_ch.erase(iter);
    55 break;
    56 case '/':
    57 index = iter-vec_ch.begin();
    58 result_temp=vec_d[index]/vec_d[index+1];
    59
    vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    +index)),result_temp);
    60 vec_ch.erase(iter);
    61 break;
    62 case '+':
    63 index = iter-vec_ch.begin();
    64 result_temp=vec_d[index]+vec_d[index+1];
    65
    vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    +index)),result_temp);
    66 vec_ch.erase(iter);
    67 break;
    68 case '-':
    69 index = iter-vec_ch.begin();
    70 result_temp=vec_d[index]-vec_d[index+1];
    71
    vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    +index)),result_temp);
    72 vec_ch.erase(iter);
    73 break;
    74 default:
    75 ;
    76 }
    77 if(/*vec_d.size()!=1*/vec_ch.size()!=0){
    78 for(vector<double>::const_iterator
    i=vec_d.begin();i!=vec_d.end();++i)
    79 cout << *i << endl;
    80 cout << "------------"<<endl;
    81 performer(vec_d,vec_ch);
    82 }
    83 else
    84 return vec_d[0];
    85 }
    86 int main(int argc, char *argv[]){
    87 if(argc!=2){
    88 cout << "Usage error should be: <program_name
    <mathematical expression> >" << endl;
    89 cout << "Example: operator 1.3+3.2+.
    1+40/3*8/7-4*5-32" << endl;
    90 return EXIT_FAILURE;
    91 }
    92 // convert c-style string argument to a c++ string
    93 string arg(argv[1]);
    94 //cout << arg << endl;
    95 vector<double> nums;
    96 vector<char> ops;
    97 parse_string(arg,nums,ops);
    98 cout << performer(nums,ops) << endl;
    99 return 0;
    100}

    2: on this version, at the end vector includes only one element that
    is the result
    -------------------------

    1 // C++ way of parsing: heavy use of standard library, string parsing
    functions
    2 //
    =======================================================================
    =====
    3 #include <iostream>
    4 #include <string>
    5 #include <vector>
    6 #include <sstream>
    7 #include <algorithm>
    8 #include <cstdlib>
    9 using namespace std;
    10
    11 template <typename T>
    12 T str_To_num (const std::string & s)
    13 {
    14 T result;
    15 std::istringstream stream (s);
    16 if (stream >> result)
    17 return result;
    18 else{
    19 cerr << "error in conversion" <<endl;
    20 return EXIT_FAILURE;
    21 }
    22 }
    23 void parse_string(const
    string&str,vector<double>&string_num_vec,vector<char>&operators_vec){
    24 string str_temp=str;
    25 string operators("+-*/");
    26 string value;
    27 string::size_type index;
    28 while((index=str_temp.find_first_of(operators))!
    =string::npos){
    29 operators_vec.push_back(str_temp[index]);
    30 value=str_temp.substr(0,index);
    31
    string_num_vec.push_back(str_To_num<double>(value));
    32 str_temp=str_temp.substr(index+1);
    33
    if(str_temp.find_first_of(operators)==string::npos)
    34
    string_num_vec.push_back(str_To_num<double>(str_temp));
    35 }
    36 }
    37 void performer(vector<double>&vec_d,vector<char>&vec_ch){
    38 double result_temp;
    39 string md("*/");
    40 string pm("+-");
    41 vector<char>::iterator iter;
    42 vector<int>::size_type index;
    43
    if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
    )!=vec_ch.end())
    44 ;
    45 else
    if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),pm.begin(),pm.end())
    )!=vec_ch.end())
    46 ;
    47 else
    48 ;
    49 switch (*iter){
    50 case '*':
    51 index = iter-vec_ch.begin();
    52 result_temp=vec_d[index]*vec_d[index+1];
    53
    vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    +index)),result_temp);
    54 vec_ch.erase(iter);
    55 break;
    56 case '/':
    57 index = iter-vec_ch.begin();
    58 result_temp=vec_d[index]/vec_d[index+1];
    59
    vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    +index)),result_temp);
    60 vec_ch.erase(iter);
    61 break;
    62 case '+':
    63 index = iter-vec_ch.begin();
    64 result_temp=vec_d[index]+vec_d[index+1];
    65
    vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    +index)),result_temp);
    66 vec_ch.erase(iter);
    67 break;
    68 case '-':
    69 index = iter-vec_ch.begin();
    70 result_temp=vec_d[index]-vec_d[index+1];
    71
    vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    +index)),result_temp);
    72 vec_ch.erase(iter);
    73 break;
    74 default:
    75 ;
    76 }
    77 if(/*vec_d.size()!=1*/vec_ch.size()!=0){
    78 performer(vec_d,vec_ch);
    79 }
    80 //else
    81 // return vec_d[0];
    82 }
    83 int main(int argc, char *argv[]){
    84 if(argc!=2){
    85 cout << "Usage error should be: <program_name
    <mathematical expression> >" << endl;
    86 cout << "Example: operator 1.3+3.2+.
    1+40/3*8/7-4*5-32" << endl;
    87 return EXIT_FAILURE;
    88 }
    89 // convert c-style string argument to a c++ string
    90 string arg(argv[1]);
    91 //cout << arg << endl;
    92 vector<double> nums;
    93 vector<char> ops;
    94 parse_string(arg,nums,ops);
    95 //cout << performer(nums,ops) << endl;
    96 performer(nums,ops);
    97 for(vector<double>::const_iterator iter=nums.begin();iter!
    =nums.end();++iter)
    98 cout << *iter << endl;
    99 //for(vector<char>::const_iterator iter=ops.begin();iter!
    =ops.end();++iter)
    100 // cout << *iter << endl;
    101 return 0;
    102 }
     
    utab, Jan 28, 2007
    #1
    1. Advertising

  2. utab

    noone Guest

    On Sun, 28 Jan 2007 08:28:26 -0800, utab wrote:

    > Dear all,
    >
    > I tried sth easy(actually this was an exercise) but I tried to use the
    > standard lib. heavily for this problem(as far as I can). There was one
    > point I could not figure out. The problem is :
    >
    > ./a.out 1.3+3.2+.1+40/3*8/7-4*5-32
    >
    > The program will parse the argument and find the result of the above
    > expression. I have two versions(the 2nd is working , not perfect ;-}), but
    > the first have a return problem I guess because if I use that version I
    > get "nan" as the result at line 37. What is my problem?
    >
    > Sorry that there are some comments and cout statement in around the code.
    > But I guess it could be easier to figure out.
    >


    ummm....

    I was going to suggest that you read the "dragon book" but upon closer
    examination consider this. Since you are calling a.out remember that UNIX
    shells usually expand '*' characters to wildcards. Quote your expression
    then see what happens.
     
    noone, Jan 29, 2007
    #2
    1. Advertising

  3. utab

    Ondra Holub Guest

    > 37 double performer(vector<double>&vec_d,vector<char>&vec_ch){
    > 38 double result_temp;
    > 39 string md("*/");
    > 40 string pm("+-");
    > 41 vector<char>::iterator iter;
    > 42 vector<int>::size_type index;
    > 43
    > if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),md.begin(),md.end())
    > )!=vec_ch.end())
    > 44 ;
    > 45 else
    > if((iter=find_first_of(vec_ch.begin(),vec_ch.end(),pm.begin(),pm.end())
    > )!=vec_ch.end())
    > 46 ;
    > 47 else
    > 48 ;
    > 49 switch (*iter){
    > 50 case '*':
    > 51 index = iter-vec_ch.begin();
    > 52 result_temp=vec_d[index]*vec_d[index+1];
    > 53
    > vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    > +index)),result_temp);
    > 54 vec_ch.erase(iter);
    > 55 break;
    > 56 case '/':
    > 57 index = iter-vec_ch.begin();
    > 58 result_temp=vec_d[index]/vec_d[index+1];
    > 59
    > vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    > +index)),result_temp);
    > 60 vec_ch.erase(iter);
    > 61 break;
    > 62 case '+':
    > 63 index = iter-vec_ch.begin();
    > 64 result_temp=vec_d[index]+vec_d[index+1];
    > 65
    > vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    > +index)),result_temp);
    > 66 vec_ch.erase(iter);
    > 67 break;
    > 68 case '-':
    > 69 index = iter-vec_ch.begin();
    > 70 result_temp=vec_d[index]-vec_d[index+1];
    > 71
    > vec_d.insert(vec_d.erase(vec_d.erase(vec_d.begin()
    > +index)),result_temp);
    > 72 vec_ch.erase(iter);
    > 73 break;
    > 74 default:
    > 75 ;
    > 76 }
    > 77 if(/*vec_d.size()!=1*/vec_ch.size()!=0){
    > 78 for(vector<double>::const_iterator
    > i=vec_d.begin();i!=vec_d.end();++i)
    > 79 cout << *i << endl;
    > 80 cout << "------------"<<endl;
    > 81 performer(vec_d,vec_ch);


    Here is undefined return value.

    > 82 }
    > 83 else
    > 84 return vec_d[0];
    > 85 }


    You should try to compile it with all warnings turned on. Then you
    will see, that in function perform is sometimes undefined returned
    value, because it simply does not return any value.
     
    Ondra Holub, Jan 29, 2007
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. max(NaN,0) should be NaN

    , Aug 28, 2006, in forum: C Programming
    Replies:
    61
    Views:
    1,280
    Michel Hack
    Sep 8, 2006
  2. utab
    Replies:
    6
    Views:
    273
  3. Replies:
    6
    Views:
    1,561
    Richard Tobin
    Mar 19, 2009
  4. Josselin

    NaN return

    Josselin, Mar 31, 2007, in forum: Ruby
    Replies:
    5
    Views:
    139
    Josselin
    Apr 10, 2007
  5. J Lake

    NaN and function not returning value.

    J Lake, May 4, 2004, in forum: Javascript
    Replies:
    5
    Views:
    100
    Michael Winter
    May 4, 2004
Loading...

Share This Page