From: David Thompson on
On Thu, 3 Dec 2009 05:42:42 +0000 (UTC), glen herrmannsfeldt
<gah(a)ugcs.caltech.edu> wrote:

> Frank <frank(a)example.invalid> wrote:
<snip>
> > [TRANSFER] is approximately equivalent to the C concept of
> > casting one type to another.
>
> C casts do the appropriate conversion. If you want to see the
> bits through casts you have to dereference a pointer cast to
> a pointer to a different type, though in that case the standard
> does not guarantee the result.
>
In general it doesn't; there are some limited cases it does.

> To do it following the standard (at least C90), you cast a
> pointer to (unsigned char *), memcpy() the bits to a variable
> through a pointer also cast to (unsigned char *).
>
I think you're conflating two things here.

(In C) You can access the 'representation' (storage) of any 'object'
(variable, more or less) as an array of unsigned-char aka byte, using
a pointer to that type, and in particular copy it to another object of
the same size, or part of a larger one. Except for the same type and
the limited variations mentioned above, there is no guarantee that the
resulting object value is usable, even readable.

As well as writing your own code, you can call memcpy() to do such a
copy. The 'parameters' (dummies/formals) of memcpy() are 'void*' and
any data pointer converts to this type without a cast, although you
can write the redundant cast if you wish. Although not explicitly
specified, the effect is the same as copying u-char's because that's
the only type guaranteed to have all value bits and no trap reps.
(Similarly memcmp() takes void* but compares as u-char's; perhaps more
surprisingly strcmp() compares as u-char's even though its arguments
are C-strings, defined as consisting of 'plain' char's which depending
on the implementation may be signed.)

From: frank on
steve wrote:
> On Dec 7, 12:13 am, Frank <fr...(a)example.invalid> wrote:
>> On Fri, 4 Dec 2009 17:16:19 -0500, Dan Nagle wrote:
>>> Hello,
>>> On 2009-12-04 15:23:47 -0500, frank <fr...(a)example.invalid> said:
>>> <snip bits from a logical>
>>>> Does that look right?
>>> It's either right or wrong, depending.
>>> Logicals have two values, true and false.
>>> These may be encoded at the processor's whim.
>>> I have seen zero v nonzero, positive v negative,
>>> even v odd, and probably something else I can't recall.
>>> Others have, no doubt, seen other encodings.
>>> That way are dragons.
>> This shakes my faith a little bit. Do C and Fortran have the same bit
>> model for a float/default real?
>>
>
> Well, I've read this entire thread, and once again I'm confused
> by what you're trying to accomplish.
>
> laptop:kargl[224] cat a.c b.f90
> #include <stdio.h>
>
> void
> cfcn_(float *x)
> {
> union a {
> int i;
> float x;
> } u;
>
> u.x = *x;
>
> printf("%d %x %f %a\n", u.i, u.i, u.x, u.x);
> }
>
> program a
> external cfcn
> real x
> integer i
> x = 3.141526
> call cfcn(x)
> i = transfer(x,i)
> print '(I0,1X,Z8,1X,F8.6)', i, i, x
> end program a
>
> laptop:kargl[225] cc -c a.c
> laptop:kargl[226] gfc4x -o z b.f90 a.o
> laptop:kargl[227] ./z
> 1078529731 40490ec3 3.141526 0x1.921d86p+1
> 1078529731 40490EC3 3.141526
>
> Note, Fortran appears to lack an edit desciptor that
> corresponds to C %a.
>
> --
> steve

Thx, steve. I had similar results when I ran your source.

I'm not sure what that means, but I'm going to take a stab at it: the
ones and zeroes in gcc's idea of a float are the same as gfortran's idea
of a default real.

I replicated your results then added some things on the C side that
didn't work out for me, and I recall my Waterloo. I could not remember
the edit descriptor for a float and wasn't willing to trot %f out there
halfass.

I don't seem to forget the fortran equivalent:

real x
x = 3.14
print *, x
endprogram

--
frank
From: glen herrmannsfeldt on
frank <frank(a)example.invalid> wrote:
(snip)

> I'm not sure what that means, but I'm going to take a stab at it: the
> ones and zeroes in gcc's idea of a float are the same as gfortran's idea
> of a default real.

> I replicated your results then added some things on the C side that
> didn't work out for me, and I recall my Waterloo. I could not remember
> the edit descriptor for a float and wasn't willing to trot %f out there
> halfass.

Arguments to varargs functions like printf are promoted, such
that (float) are converted to (double) before the call.

The conversion specifiers %f, %e, and %g work somewhat similarly
to the Fortran F, E, and G format descriptors. The width is a
minimum, with fields expanding as needed, with an implementation
defined default.

> I don't seem to forget the fortran equivalent:

> real x
> x = 3.14
> print *, x
> endprogram

-- glen
From: frank on
glen herrmannsfeldt wrote:

> Arguments to varargs functions like printf are promoted, such
> that (float) are converted to (double) before the call.
>
> The conversion specifiers %f, %e, and %g work somewhat similarly
> to the Fortran F, E, and G format descriptors. The width is a
> minimum, with fields expanding as needed, with an implementation
> defined default.

Do you know what the promotions are doing here:
i = ((double) rand () / ((double) RAND_MAX + 1) * N);
, where the i object is of type int?


http://c-faq.com/lib/index.html It's part of 13.16 here.
--
frank
From: steve on
On Jan 11, 7:58 pm, frank <fr...(a)example.invalid> wrote:
> glen herrmannsfeldt wrote:
> > Arguments to varargs functions like printf are promoted, such
> > that (float) are converted to (double) before the call.
>
> > The conversion specifiers %f, %e, and %g work somewhat similarly
> > to the Fortran F, E, and G format descriptors.  The width is a
> > minimum, with fields expanding as needed, with an implementation
> > defined default.  
>
> Do you know what the promotions are doing here:
> i = ((double) rand () / ((double) RAND_MAX + 1) * N);
> , where the i object is of type int?
>
> http://c-faq.com/lib/index.html It's part of 13.16 here.

Wrong group. Should have posted to comp.lang.c.

--
steve