Thread: Math problem: it thinks that 0-1=4 million

  1. #1
    Registered User
    Join Date
    Mar 2006
    Posts
    40

    Math problem: it thinks that 0-1=4 million

    I have the oddest problem now that I can't figure out. In my GetAngle function, I have a float that is the difference of two other floats and it is not calculating right. I have stripped everything else out of the function and it now looks like this in my project and yet it does not work:
    Code:
    float GetAngle(point targ, point ref)
    {                                 
      float y = targ.y-ref.y;
      string temp = num2text(targ.y)+"-"+num2text(ref.y)+"="+num2text(targ.y-ref.y);
      TextOut(GetDC(hWnd), 10, 10, temp.c_str(), temp.length());
      return 0.0f;
    }
    It is showing "0.000-1.000=4294966.296"

    Does anyone know why it could be doing this?

    Thanks in advance for any help.

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Data types are the most important thing, and you've not shown some of the key ones, like the members of point, or even the function declaration of num2text. [edit]In fact, it is always best to post a minimal compileable snippet that demostrates the problem -- to do otherwise is to expect anyone wishing to help you to reinvent what you're looking at.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Registered User
    Join Date
    Mar 2006
    Posts
    40
    I didn't see how that could affect the output there, unless it was num2text's fault, but I haven't had a problem with that function yet. Either way, here they are.
    Code:
    //my point class
    class point
    {
      public:
      float x, y, z;
    };
    
    //my num2text function
    //The num2text(int) is the main one, and num2text(float) just calls num2text(int) then adds the period in after
    string num2text(float n)
    {
      //It calls num2text(int), multiplying n by 1000 to preserve 3 digits past the decimal
      unsigned long int temp = (long)(n*1000);
      string return_value = num2text(temp);
      if(return_value == "0")
      {
        return_value = "0.000";
      }
      else
      {
        //the rest just adds the "." in three places from the end
        while(return_value.length() < 3)
        {
          return_value = "0" + return_value;
        }
        return_value.insert(return_value.length()-3, ".");
        if(return_value[0] == '.')
        {
          return_value = "0" + return_value;
        }
      }
      return return_value;
    }
    string num2text(unsigned long int n)
    {
      //This one just starts at a billion and works its way down through the digits to 1
      //it continually subtracts from n and adds to the text string
      unsigned long int place_value = 1000000000;
      unsigned long int place_holder = 0;  //keeps track of the number at the current digit pointed to by place_value
      bool first_place_passed = false;  //keeps track of whether we've come across our first valid digit yet, and therefor if it should append to return_value
      string return_value = "";
      if(n == 0)
      {
        return_value = "0";
        return return_value;
      }
      while(n >= 0)
      {
        while(n >= place_value)
        {
          n -= place_value;
          place_holder += 1;
        }
        if(place_holder != 0 || first_place_passed)
        {
          first_place_passed = true;
          return_value += (char)place_holder+48;
        }
        place_value /= 10;
        place_holder = 0;
        if(n == 0 && place_value < 1)
        {
          break;
        }
      }
      return return_value;
    }
    Whether or not num2text is faulty, it wasn't what alerted me in the first place. I use the return value from the function (though, as you can see, it doesn't return much since I've stripped things out while debugging) and the return value was not as it was supposed to be.
    Last edited by Loduwijk; 07-26-2006 at 08:35 PM.

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I'm not looking very closely at what you posted, because I see the floating point to integral conversion. Which looks much like this:
    Code:
    #include <iostream>
    
    int main()
    {
       std::cout << (unsigned int)-1.0 << '\n';
       return 0;
    }
    
    /* my output
    4294967295
    */
    Same issue.

    http://www.parashift.com/c++-faq-lit....html#faq-39.1

    [edit]Throwing that together:
    Code:
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <stdexcept>
    
    class BadConversion : public std::runtime_error
    {
    public:
       BadConversion(const std::string& s) : std::runtime_error(s) {}
    };
    
    inline std::string stringify(double x)
    {
       std::ostringstream o;
       if ( !(o << x) )
          throw BadConversion("stringify(double)");
       return o.str();
    }
    
    class point
    {
    public:
       float x, y, z;
       point(float x_ = 0, float y_ = 0, float z_ = 0) : x(x_), y(y_), z(z_) {}
    };
    
    float GetAngle(point targ, point ref)
    {
       float y = targ.y - ref.y;
       std::string temp = stringify(targ.y) + "-" + 
                          stringify(ref.y)  + "=" +
                          stringify(targ.y - ref.y);
       std::cout << temp << '\n';
       return y;
    }
    
    int main()
    {
       point a, b(1,1,1);
       std::cout << GetAngle(a,b) << '\n';
       return 0;
    }
    
    /* my output
    0-1=-1
    -1
    */
    Last edited by Dave_Sinkula; 07-26-2006 at 08:46 PM. Reason: Added code.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Registered User
    Join Date
    Mar 2006
    Posts
    40
    Ah yes, thank you. I wasn't thinking about the unsigned integer part. That makes sense that it would cycle back around to the maximum value of the unsigned long int from the num2text function.

    I made it signed and that at least reduced the number. However, things still aren't adding up somewhere. I'm still getting odd math, such as 0.5*0.5 being set to 1.118 and 0-1=0.

    Thanks for the step in the right direction. I might reply to this if I realise where the problem is but can't fix it. I'll tinker with it for now though.

    (edit)
    How silly of me. I change num2text to accept negative numbers, and I expect it to still work. It's telling me 0-1=0 because it isn't designed to handle numbers less than 0, obviously. I fixed it so that it displays negative numbers properly and it's showing everything fine now.

    Thanks again. I still have bugs, but at least they'll be easier to track down now that my debug output is not screwy.
    (/edit)
    Last edited by Loduwijk; 07-26-2006 at 09:05 PM.

  6. #6
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    >> string num2text(float n)

    Did you need to make that function? Couldn't you have just used itoa?

    EDIT - Here's an example I used when I had to download 3000 files, but didn't want to do it manually. The files which I downloaded changed according to a date - starting in 85, and endint in 95 or something like that.

    (The coloring program I used crashes when I put this code through it, so ye'll have to bear with regular code ... sigh)

    Code:
        string    FromSite    = "http://something.com/";
        string    ToFile        = "C:\\";
        int        Year        = 85,
                Month        = 11,
                Date        = 17;
        bool    EndMonth    = false;
        char    Temp[20];
    
    
        // Append Dates
        itoa( Year,  Temp, 10 );
        FromSite.insert    ( FromSite.length (), Temp );
        ToFile.insert    ( ToFile.length(),     Temp );
    
       
        FromSite.insert    ( FromSite.length(), "/ch" );
        FromSite.insert    ( FromSite.length(), Temp );
    
        if  ( Month<=9 )
        {
            itoa( 0, Temp, 10 );
    
            FromSite.insert    ( FromSite.length(), Temp );
            ToFile.insert    ( ToFile.length(),     Temp );
        }
        itoa( Month, Temp, 10 );
        FromSite.insert ( FromSite.length(), Temp );
        ToFile.insert    ( ToFile.length(),     Temp );
    
        if  ( Date<=9 )
        {
            itoa( 0, Temp, 10 );
    
            FromSite.insert    ( FromSite.length(), Temp );
            ToFile.insert    ( ToFile.length(),     Temp );
        }
        itoa( Date,  Temp, 10 );
        FromSite.insert ( FromSite.length(), Temp );
        ToFile.insert    ( ToFile.length(),     Temp );
    
        FromSite.insert     ( FromSite.length(), ".gif" );
        ToFile.insert    ( ToFile.length(),     ".gif" );
    etc. The rest of this code is irrelevant to the thread.
    Last edited by twomers; 07-27-2006 at 05:45 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. slight math problem sorry
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 08-21-2002, 11:48 AM
  2. one math problem
    By SuperNewbie in forum Windows Programming
    Replies: 1
    Last Post: 06-03-2002, 04:41 PM
  3. a math problem . . . i hope atleast
    By blight2c in forum C++ Programming
    Replies: 7
    Last Post: 05-26-2002, 02:23 PM
  4. problem with output
    By Garfield in forum C Programming
    Replies: 2
    Last Post: 11-18-2001, 08:34 PM
  5. Little math problem
    By Thantos in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 10-27-2001, 07:44 PM