On Mon, 11 Aug 2003 23:46:38 GMT, Carl Banks wrote: Terry Reedy wrote:
No, quite different. A C cast (at least usually) recasts a block of
bits in a new role without changing the bits.
Certainly not. Most type casts actually change bits. For example,
supposing floats and longs are both 32 bits, the expression (float)1L
will *not* return the floating point number with the same bit pattern
as 1L. It returns 1.0.
Usually, the only casts that preserve the bit pattern are integer to
pointer casts, and the C standard doesn't even guarantee that (unless
C 2000 changed it). In fact, the C standard says (or used to say)
that 0 must always cast to a null pointer, even if the system
represents integer 0 and null pointer with different bits, which does
(or used to) happen.
IMO, a type cast is just a fancy name for an operator that takes an
object and returns an object with the same "value" (whatever that
means) but a different type. In C, type casting happens to have a
funny syntax. In Python, it does not. If someone asked, "does Python
have type casting?", I would say yes, except there's no special syntax
for it. Rather, type casting is done by the calling type objects
themselves.
Well, there is one way to look at existing bits exactly as they are in
terms of an alternate type representation. The easy way is to do reinterpret cast
on a pointer to change a pointer to the old type into a pointer to a new type,
without changing location. E.g., how else to print out the bit representation
of something? E.g., here's a hack to see floats and doubles as little-ending python strings:
====< castf.c >======================================
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
float f4;
double f8;
int i;
if(argc<2){ printf("Usage: castf <floating point number for atof>\n"); return 0;}
f8 = atof(argv[1]); f4=f8;
printf("\"");
for(i=0; i<sizeof(f4); ++i){ printf("\\x%02x",((unsigned char *)(&f4))[i]);};
printf("\"\n");
printf("\"");
for(i=0; i<sizeof(f8); ++i){ printf("\\x%02x",((unsigned char *)(&f8))[i]);};
printf("\"\n");
return 0;
}
=====================================================
[18:04] C:\pywk\clp>castf
Usage: castf <floating point number for atof>
[18:04] C:\pywk\clp>castf 1.625
"\x00\x00\xd0\x3f"
"\x00\x00\x00\x00\x00\x00\xfa\x3f"
[18:04] C:\pywk\clp>castf -1.625
"\x00\x00\xd0\xbf"
"\x00\x00\x00\x00\x00\x00\xfa\xbf"
[18:04] C:\pywk\clp>castf 0
"\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
[18:04] C:\pywk\clp>castf 1
"\x00\x00\x80\x3f"
"\x00\x00\x00\x00\x00\x00\xf0\x3f"
[18:04] C:\pywk\clp>castf -1
"\x00\x00\x80\xbf"
"\x00\x00\x00\x00\x00\x00\xf0\xbf"
Actually, it's a little confusing to look at numbers in that order, especially
since the hex for the bits in the bytes is big-end-on-the-left ;-)
2**54-1 (naturally I used python to get the number ;-)
[18:12] C:\pywk\clp>castf 18014398509481983
"\x00\x00\x80\x5a"
"\xff\xff\xff\xff\xff\xff\x4f\x43"
2**53-1
[18:12] C:\pywk\clp>castf 9007199254740991
"\x00\x00\x00\x5a"
"\xff\xff\xff\xff\xff\xff\x3f\x43"
2**52-2**12
[18:12] C:\pywk\clp>castf 9007199254736896
"\x00\x00\x00\x5a"
"\x00\xf0\xff\xff\xff\xff\x3f\x43"
^^ ^-bits 8-11 (the f is bits 12-15)
^^-bits 0-7
Of course, the cleaner way would have been to factor that instead of cutting and pasting:
Some architectures might not like addressing arbitrary bytes, but we'll leave that as exercise
material ;-)
====< castf.c >======================================
#include <stdio.h>
#include <stdlib.h>
void prnch(void *pthing, int n){
int i;
printf("\"");
for(i=0; i<n; ++i){ printf("\\x%02x",((unsigned char *)(pthing))[i]);};
printf("\"\n");
}
int main(int argc, char *argv[]){
float f4; double f8;
if(argc<2){ printf("Usage: castf <floating point number for atof>\n"); return 0;}
f8 = atof(argv[1]); f4=f8;
prnch(&f4, sizeof(f4));
prnch(&f8, sizeof(f8));
return 0;
}
==========================================
Regards,
Bengt Richter