home bbs files messages ]

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

   comp.lang.c      Meh, in C you gotta define EVERYTHING      243,242 messages   

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

   Message 242,173 of 243,242   
   Waldek Hebisch to bart   
   Re: _BitInt(N)   
   27 Nov 25 02:32:08   
   
   From: antispam@fricas.org   
      
   bart  wrote:   
   >   
   > This is about a lower-level systems language working with primitive   
   > machine types, and having access to the underlying bits of those types.   
   >   
   > How much more fundamental can you get?   
   >   
   > C provides only basic bitwise operators, and you have to do some   
   > bit-fiddling, while trying to avoid UB, in order to extract or inject   
   > individual bits or bitfields.   
   >   
   > I provide direct indexing ops to get or set any bit or bitfield, which   
   > is actually a great core feature to have, but for some reason you want   
   > to downplay it.   
   >   
   > You might just admit for once that it is quite neat.   
      
   Yes, it is neat.   
      
   >>  (It can be an important operation - such as for software   
   >> floating point routines.   
   >   
   > That particular task can be important for lots of reasons.   
   >   
   >>  But the people who write those are few, and   
   >> they know what they are doing.)   
   >   
   > And I don't? I used to write FP emulation routines...   
   >   
   >   
   >> "Type punning" refers to using a union to access or reinterpret the   
   >> underlying bit representation.  Using references and a cast to do so is   
   >> UB,   
   >   
   > In C maybe, using your favoured compilers. In my implementations of C,   
   > and in my languages, it is well defined, especially as it is   
   > type-punning a 64-bit quantity to another 64-bit quantity.   
   >   
      
   >   
   > OK, so how would you do a 'reinterpret' cast in C, of a value like 'x+y'?   
      
   #include    
   #include    
      
   uint64_t   
   d_to_u(double d) {   
       uint64_t tmp;   
       memcpy(&tmp, &d, sizeof(tmp));   
       return tmp;   
   }   
      
   int   
   f_exp(double d) {   
      return (d_to_u(d)>>52)&2047;   
   }   
      
   Using 'gcc -O' I get the following assembly (only code, without   
   unimportant directives/labels):   
      
   d_to_u:   
           movq    %xmm0, %rax   
           ret   
      
   f_exp:   
           movq    %xmm0, %rax   
           shrq    $52, %rax   
           andl    $2047, %eax   
           ret   
      
   As you can see 'd_to_u' is single computational instruction,   
   you can not do better given that floating point registers   
   are distinct from integer registers.  And 'f_exp' looks   
   optimal assuming lack of "bit extract" or "extract exponent"   
   instructions.   
      
   Note that you can put both functions above in a header file,   
   so once you have written few lines above you can use them   
   in all your C code.  Of course, efficientcy depends on   
   compiler optimization.   
      
   --   
                                 Waldek Hebisch   
      
   --- 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