#1
  1. Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2003
    Posts
    15
    Rep Power
    0

    Who wants to play find that bug?


    I'm trying to program a function that will convert an integer value to binary for the purpose of viewing the flags passed by uMsg in a DOS output window. I went through it step by step and based one what I know it should work, but then again I'm a newbie to C++. Anyway, for some reason, this function always return the value 0x0 and I can't figure out why. Any ideas? Btw, here is the page I based my algorithm on: http://www.muine.org/~minhqt/Nax_web...ry.html#binary

    INT ViewIntAsBin(INT intVar)
    {

    int intReturnedVar = 0;
    int Counter = 0;

    while(intVar > 0)
    {

    if((int)floor(intVar / 2) != (intVar / 2))
    {
    intReturnedVar = intReturnedVar + (int)pow(10, Counter);
    }

    intVar = (int)floor(intVar / 2);
    Counter++;
    }

    return intReturnedVar;
    }
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222

    Re: Who wants to play find that bug?


    Here's the short answer:
    The expression (intVar / 2), wherein intVar is an integer, will always perform integer division which always returns only the quotient; the remainder is always lost.
    Therefore, ((int)floor(intVar / 2) != (intVar / 2)) will never be true and you will never have any of the bits in your return value set to one; the ViewIntAsBin function will always return a zero.

    Solution:
    If you want to keep your approach, do floating-point division instead.

    Better Solution (IMHO):
    Keep the integer division, but make use of the modulo operator (%) which returns the remainder of an integer division -- if x is even, then (x % 2) is zero and if x is odd, then (x % 2) is one.
    Also, instead of using the pow function, why not just initialize a variable to 1 and then shift it left each loop; eg:
    Code:
    int iBit = 1;
    
    while (intVar > 0)
    {
        if (intVar % 2)  // there is a remainder
            intReturnedVar += iBit;
    
        intVar /= 2;
        iBit *= 10;
    }
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    LOL! I completely missed the final goal!

    You don't want to do your function that way. You want to output a string that contains the binary representation of the number. By returning an integer, your function should return the same value that you had passed to it. Although that would be a way of testing the validity of the function, it won't help you to display the number in binary.

    OK, here's a thought. You already know the maximum number of bits to expect in that string -- eg, if int is 16 bits long, then the resultant string could only be 16 characters long, plus one for the null termination. Initialize the string to all zeros. Make the iBit variable an index pointer into the string -- or use a character pointer if you wish -- and initialize it to point to the last displayable character in the string, to the one's place. Then iterate through as we've been doing, only set the indexed character to a '1' based on (intVar % 2) and decrement the index at the end of the loop.

    That should do the job (I haven't tried it yet, but it looks right to me).

    Sorry I missed the final purpose of your function like that.
  6. #4
  7. Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2003
    Posts
    15
    Rep Power
    0
    lol, I can't believe I forgot ant integer variable won't hold a decimal. Thanks a lot for the help, I wasn't even sure how the +=, /=, ect. operators were supposed to work before I saw your example.
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally posted by Xzyx987X
    lol, I can't believe I forgot ant integer variable won't hold a decimal. Thanks a lot for the help, I wasn't even sure how the +=, /=, ect. operators were supposed to work before I saw your example.
    Yeah, they're just programming shorthand. When I went from Pascal (designed by academics to teach structured programming to students) to C (designed by programmers to do programming) I was immediately struck by the relative terseness of C. I concluded that programmers don't like to type.
  10. #6
  11. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,648
    Rep Power
    4248
    >> but make use of the modulo operator (%) which
    You can also use the bitwise and as well as the shift operator, which may make things even faster. Bitwise operations are a few orders of magnitude faster than division or modulo operations.
    Code:
    #include <stdio.h>
    
    int IntToBin(int val);
    
    int main(void) {
      int x = 37;
      printf("%d is %d in binary\n", x, IntToBin(x));
      return 0;
    }
    
    int IntToBin(int intVar) {
      int intBit = 1;
      int intReturnedVar = 0;
      int intMask = 0x1;
    
      while (intMask < intVar) {
        if (intVar & intMask)
          intReturnedVar += intBit;
        intBit *= 10;
        intMask <<= 1;
      }
      return intReturnedVar;
    }
  12. #7
  13. Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2003
    Posts
    15
    Rep Power
    0
    By returning an integer, your function should return the same value that you had passed to it.
    Huh, what do you mean? Yes, the number returned was still technically an integer in the computer's memory, but doing it this way still displays it in binary (granted without any leading zeros.)

    You can also use the bitwise and as well as the shift operator, which may make things even faster. Bitwise operations are a few orders of magnitude faster than division or modulo operations.
    Actually speed isn't really an issue here since this is just a degug function. Thanks anyway though. Uh, would you mind expaining what <<= is supposed to do and why you declared intMask as 0x1 instead of just 1? Actually the function appears to be incorrect since it interprets IDOK as 0x0 when it should be 0x1.
  14. #8
  15. Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2003
    Posts
    15
    Rep Power
    0
    Ah, here it is:

    while (intMask < intVar) {

    Since intMast starts out as one in this case, if intVar is one too then the while statement will skip itself.
  16. #9
  17. Banned ;)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Nov 2001
    Location
    Woodland Hills, Los Angeles County, California, USA
    Posts
    9,648
    Rep Power
    4248
    Good catch! Change it to :
    while (intMask <= intVar) {
    and it should work.
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally posted by Xzyx987X
    Huh, what do you mean? Yes, the number returned was still technically an integer in the computer's memory, but doing it this way still displays it in binary (granted without any leading zeros.)
    Originally, your function received an integer value and created another integer value based on which bits on the input integer are set. If the function is operating correctly, then the resultant integer should end up with the same value as the input integer.

    In order to display the input integer value, you need to convert it to a character string. For most numeric values, this is done with a formatted-print function, either of the printf family or through the overloading of the << operator in iostreams.

    You say that you are indeed displaying it in binary. Could you please tell us how?
  20. #11
  21. Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2003
    Posts
    15
    Rep Power
    0
    Originally, your function received an integer value and created another integer value based on which bits on the input integer are set. If the function is operating correctly, then the resultant integer should end up with the same value as the input integer.
    Not necessarily. In this case all I wanted was to get the output to look like it was in binary, not to actually be in binary in terms of memory. The reason I was still storing it as an integer was to work around the fact I didn't know how to dispay a variable in binary format or even create one for that matter.

    In order to display the input integer value, you need to convert it to a character string. For most numeric values, this is done with a formatted-print function, either of the printf family or through the overloading of the << operator in iostreams.
    Or, you could just use a %d in the printf function as I did.

    You say that you are indeed displaying it in binary. Could you please tell us how?
    You should know, using the code you wrote I was able to get the function to produce binary output just fine.
  22. #12
  23. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally posted by Xzyx987X
    Not necessarily. In this case all I wanted was to get the output to look like it was in binary, not to actually be in binary in terms of memory.
    Actually, all data in a computer is always in binary. All that's different is how we tell the computer to interpret it. Slight technicality.


    Or, you could just use a %d in the printf function as I did.
    Actually, since the bits are easy to read off on sight in hexadecimal, I usually use %x. Besides, if those binary bit strings get too long, I start to lose count.


    You should know, using the code you wrote I was able to get the function to produce binary output just fine.
    Farm out! Not bad for having come up with it off the top of my head.

    Glad to have been of service. Share and enjoy!
  24. #13
  25. Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2003
    Posts
    15
    Rep Power
    0
    Actually, all data in a computer is always in binary. All that's different is how we tell the computer to interpret it. Slight technicality.
    Good point, that's easy to forget when you're dealing with a language that handles memory so strictly. Of couse I know the reason for this is to avoid bugs, although in my case it ended up causing one (in my first attempt of the function.) I guess their is no perfect solution for dealing with human nature :D

IMN logo majestic logo threadwatch logo seochat tools logo