home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / c / 16946 < prev    next >
Encoding:
Text File  |  1992-11-21  |  3.3 KB  |  108 lines

  1. Newsgroups: comp.lang.c
  2. Path: sparky!uunet!uunet.ca!wildcan!sq!msb
  3. From: msb@sq.sq.com (Mark Brader)
  4. Subject: Re: converting unsigned int to signed int
  5. Message-ID: <1992Nov21.123530.25926@sq.sq.com>
  6. Organization: SoftQuad Inc., Toronto, Canada
  7. References: <19226@ucdavis.ucdavis.edu> <1992Nov20.104109.21538@thunder.mcrcim.mcgill.edu>
  8. Date: Sat, 21 Nov 92 12:35:30 GMT
  9. Lines: 97
  10.  
  11. > > What is a safe, portable method of converting from signed int to
  12. > > unsigned? ... I want the most negative signed value to convert to
  13. > > 0, and the most positive signed value to (max signed int) +
  14. > > abs(max negative signed int).
  15.  
  16. I hope this isn't a homework problem... because I'm going to answer it.
  17.  
  18. What I take this to be saying is that you want to convert a value
  19. from signed int to unsigned int while adding to it the absolute
  20. value of the most negative signed int.  Okay.  If i is the signed
  21. int, and INT_MIN is the most negative signed int value, then this
  22. is simply:
  23.  
  24.     (unsigned)si - INT_MIN
  25.  
  26. This works because it will convert INT_MIN to unsigned and do the
  27. subtraction in unsigned.  The conversion and the arithmetic are
  28. guaranteed to follow modular arithmetic properties, which is exactly
  29. what we want here.
  30.  
  31. On an ANSI C system, INT_MIN is predefined for you and available by
  32.  
  33.     #included <limits.h>
  34.  
  35. On a pre-ANSI version of C, it may not be available as a predefined
  36. variable, and there is no fully portable way for you to compute or
  37. derive it within your program.
  38.  
  39.  
  40.  
  41. My further remarks below are in reference to the standard, but I'm
  42. reasonably sure that they apply to all pre-ANSI implementations too.
  43.  
  44. > This may or may not be possible.  There is no guarantee that signed and
  45. > unsigned ints have the same "range", the same number of distinct
  46. > possible values.
  47.  
  48. If they are different, the range of unsigned ints must be larger.
  49. This is because both types are guaranteed to occupy the same space,
  50. and a pure binary representation is guaranteed for nonnegative values.
  51.  
  52. > To be fully portable, you have to split it up into various cases
  53. > based on the value of the original integer.
  54.  
  55. That's the hard way.  The easy way is to do the arithmetic in the
  56. unsigned type, where you get right semantics.
  57.  
  58. >     #include <limits.h>
  59. >     signed int si;
  60. >     unsigned int ui;
  61. >     if (si <= INT_MAX+INT_MIN)
  62. >      { ui = si - INT_MIN;
  63. >      }
  64.  
  65. Fine; included here only for context.
  66.  
  67. > #if INT_MAX+INT_MIN < -1
  68. >     /* this can happen only when more than half the possible int
  69. >        values are negative - not possible with a two's complement
  70. >        binary representation, for example */
  71.  
  72. It can't happen at all.  Nonnegative numbers have to be in pure
  73. binary, and only one bit is allowed for the sign, so at least
  74. half the values have to be nonnegative.
  75.  
  76. >     else if (si < 0)
  77. >      { /* some code I don't feel like working out */
  78. >      }
  79.  
  80. Just as well. :-)
  81.  
  82. > #endif
  83. > #if UINT_MAX < INT_MAX
  84. >     /* I'm not sure whether this is allowed; my reference is at
  85. >        work and I'm at home */
  86.  
  87. No.  See above.
  88.  
  89. >     else if (s > UINT_MAX)
  90. >      { /* more messy code */
  91. >      }
  92. > #endif
  93.  
  94. Therefore, not needed.
  95.  
  96. >     else
  97. >      { ui = (unsigned int)si - (unsigned int)INT_MIN;
  98. >      }
  99.  
  100. Correct, and equivalent to my code above.  However, it does not need
  101. to be guarded by the if/else; this line does it all.
  102. -- 
  103. Mark Brader, SoftQuad Inc., Toronto, utzoo!sq!msb, msb@sq.com
  104. #define    MSB(type)    (~(((unsigned type)-1)>>1))
  105.  
  106. This article is in the public domain.
  107.