home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.lang.c++.moderated      Moderated discussion of C++ superhackery      33,346 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 32,295 of 33,346   
   Alf P. Steinbach to Seungbeom Kim   
   Re: Getting the smallest signed type tha   
   16 May 12 00:21:11   
   
   From: alf.p.steinbach+usenet@gmail.com   
      
   On 16.05.2012 06:23, Seungbeom Kim wrote:   
   > Hi all,   
   >   
   > The subject explains itself. Let's say you have a pair of objects, a and b,   
   > of an unsigned integer type U, and you want to calculate their difference   
   > in a signed integer type.   
   >   
   > Obviously you cannot simply write "a - b", because that will yield an   
   > unsigned integer value in modulo arithmetic. So you want to write   
   >   
   >       S d = static_cast(a) - static_cast(b);   
   >   
   > for a signed integer type S.   
   >   
   > The problem is, how do you determine S? Of course, S should be large enough   
   > to represent all the values of U. To be safe, you could just use S=intmax_t   
   > for every U, but that might be an overkill; if U=uint16_t, then S=uint32_t   
   > is enough, and you don't want to use more expensive arithmetic in uint64_t   
   > or uint128_t. So, something like S=int_least[N+1]_t where N=numeric_limits   
   > ::digits() would be desirable (+1 because of the sign bit).   
   >   
   > Is there a way to automatically determine S from U?   
   >   
      
   I think this should work, although I recommend primarily to avoid using   
   unsigned types for numbers, and secondly, if one must, use `ptrdiff_t`   
   for differences (after all, that's what you get for a pointer difference):   
      
      
      
   #include    
   #include    
   using namespace std;   
      
   struct CompleteVoid {};   
      
   template< class Type > struct Next;   
   template<> struct Next            { typedef unsigned char T; };   
   template<> struct Next     { typedef unsigned char T; };   
   template<> struct Next   { typedef short T; };   
   template<> struct Next           { typedef unsigned short T; };   
   template<> struct Next  { typedef int T; };   
   template<> struct Next             { typedef unsigned T; };   
   template<> struct Next        { typedef long T; };   
   template<> struct Next            { typedef unsigned long T; };   
   template<> struct Next   { typedef long long T; };   
   template<> struct Next       { typedef unsigned long long T; };   
   template<> struct Next { typedef CompleteVoid T; };   
      
   template< bool condition, class A, class B >   
   struct Choose;   
      
   template< class A, class B >   
   struct Choose< true, A, B > { typedef A T; };   
      
   template< class A, class B >   
   struct Choose< false, A, B > { typedef B T; };   
      
   template< class Type >   
   struct NextLarger   
   {   
   private:   
       typedef typename Next::T  NextUp;   
   public:   
       typedef typename Choose<   
           (sizeof(NextUp) > sizeof(Type)),   
           NextUp,   
           typename NextLarger::T   
           >::T T;   
   };   
      
   template<>   
   struct NextLarger   
   {   
   public:   
       typedef void T;   
   };   
      
   int main()   
   {   
       wcout   
           << "The signed type above & covering 'unsigned' is '"   
           << typeid( NextLarger::T ).name()   
           << "'."   
           << endl;   
   }   
      
      
      
   For g++ there is g++-specific function that produces readable type   
   names, I don't recall its name but you can easily find it.   
      
      
   Cheers & hth.,   
      
   - Alf   
      
      
   --   
         [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
         [ comp.lang.c++.moderated.    First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca