#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    4
    Rep Power
    0

    Why multiply unsigned integer by -1?


    I'm trying understand some firmware code for an AVR. The variable in question is called timer0_init and is of type uint32_t which in AVR defs is defined as an 32-bit unsigned integer.

    in the code there is the statement:
    timer0_init *= -1;

    why would you multiply an unsigned integer by -1? Would this just equal 0? Why not just say timer0_init = 0?
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    > Would this just equal 0? Why not just say timer0_init = 0?
    Why not try it for yourself, and see what result you do get (rather than just speculating).

    No, it isn't zero.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    4
    Rep Power
    0
    Why not try it for yourself
    ...because I don't understand it. If -1 is represented as unsigned (presumably 32bit) and multiplied by the value of timer0_init the resulting number would be too large to fit into a 32bit field. How would you denote -1 as an unsigned integer? I guess as two's complement so it would be all 1's? Next, how would you know how many bits to represent -1 as? If it's assumed to be an 8-bit integer it would be 11111111. If it was presumed to be a 16-bit integer it would be 1111111111111111 and so on. obviously this makes a huge difference. So how do I know how many bits to use to represent -1? Basically I guess I'd like to know how do you multiply signed an unsigned numbers together. My textbooks never mention signed an unsigned together, and nothing definitive w/ google or forum search.
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    If you dig deep enough, it's all just bits and bytes.

    The programmer could have said
    timer0_init *= 0xffffffffu;
    instead, which is an unsigned int with all the bits set (just as -1 is on a 2's complement machine).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    4
    Rep Power
    0
    The programmer could have said timer0_init *= 0xffffffffu;
    ok thanks. unless the initial value of timer0_init was 0 or 1 wouldn't the result overflow beyond 32bits? Those bit would just be thrown away?
  10. #6
  11. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    Yes, overflow is usually silent (in fact always silent for unsigned arithmetic).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    4
    Rep Power
    0
    ok then I think I figured what it's doing in the scope of the program.
    • The variable timer0_init is a 16bit integer (not 32bit as mentioned above)
    • Timer0 is a 16bit timer

    When the statement timer0_init *= -1 is computed it basically has the effect of subtracting the value of (timer0_init - 1) from the maximum 16bit value of 65535. I think in this case it is done because the program in using the timer0 overflow interrupt so if you want the counter to count from 0 to x it's the same as having it initialized to (65535 - x) and then counting to 65535 and having it throw the overflow interrupt.

    The statement could have said.
    timer0_init *= 0xFFFF; or
    timer0_init = (65535 - (timer0_init - 1));

    Comments on this post

    • salem agrees : That looks about right - good job
    • Lux Perpetua agrees

IMN logo majestic logo threadwatch logo seochat tools logo