weiser.pa@Xerox.COM (01/08/88)
I have the following problem: I have a value which I happen to know has the proper bits to represent a floating point number (either 32 or 64). However, it is of type int. I would now like to tell the C compiler to treat this thing as a float. How can I do it without taking the address of the thing (which may not have an address because it is in a register or is an expression) or using a subroutine call (for which I do not wish to pay the cost)? (If I could take an address, then the solution is: *(float *)foo).) (Needless to say, the following does NOT work: (float)foo, because it actually does a conversion of the integer foo into a float. I don't want a conversion, but rather I want the compiler to just trust me that I am handing it bits that it should consider to be a float.) Thanks for any help. Currently I'm working around the problem by using assembler in-lines as supported by Sun, but I'd like a less vendor independent method. -mark
bzs%bu-cs.bu.edu@bu-it.BU.EDU (Barry Shein) (01/08/88)
The attached program seems to work. Whether or not it ends up in a register seems to be compiler dependant but I had no complaints about the syntax and it always produced the expected results. On the Sun it ends up in a register when compiled with a -O flag but not if not. On an Encore/Multimax (Greenhill's C) and Vax (4.3bsd) it never ends up in a register. I couldn't really tell on the Celerity but I think it ends up in a register both optimized and unoptimized (I had trouble reading the machine code, not their fault, mostly I was too lazy to try to follow it carefully.) The optimizer for PCC on the 3090 (IBM370) is not available but it ended up in a register unoptimized. I'll leave it to the language lawyers as to whether or not it *should* have worked. -Barry Shein, Boston University #include <stdio.h> /* * Bit patterns for 23.7 on various machines */ #define SUN 1 #if SUN | UMAX | CELERITY #define TWENTYTHREEPTSEVEN 0x41bd999a #endif #if IBM370 #define TWENTYTHREEPTSEVEN 0x4217b333 #endif #if VAX #define TWENTYTHREEPTSEVEN 0x999a42bd #endif main() { register union foo { int a; float b; } x; float z; x.a = TWENTYTHREEPTSEVEN; /* bit pattern for 23.7 float */ z = x.b; printf("%f\n",z); }
weiser.pa@Xerox.COM (01/08/88)
Sigh. I must not have made myself sufficiently clear. Before I get any more responses to my converting-to-float request, please note that I need to convert an EXPRESSION. The UNION examples don't help. -mark
alex@umbc3.UMD.EDU (Alex S. Crain) (01/08/88)
In article <11171@brl-adm.ARPA> weiser.pa@Xerox.COM writes: >I have the following problem: I have a value which I happen to know has the >proper bits to represent a floating point number (either 32 or 64). However, it >is of type int. I would now like to tell the C compiler to treat this thing as >a float. union { float f; int i; } foo; foo.i = int value foo.f = float value -- :alex. alex@umbc3.umd.edu
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/08/88)
In article <11171@brl-adm.ARPA> weiser.pa@Xerox.COM writes: >I would now like to tell the C compiler to treat this thing as a float. C questions should go to comp.lang.c (INFO-C). Try (*(union{int i;float f;})integer).f which should work but probably will give your compiler indigestion. If that doesn't work, store it into such a union's integer member then extract the float member of the union: union {int i; float f} u; u.i = integer; expression( u.f );
gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/08/88)
In article <11175@brl-adm.ARPA> weiser.pa@Xerox.COM writes: >Sigh. I must not have made myself sufficiently clear. Before I get any more >responses to my converting-to-float request, please note that I need to convert >an EXPRESSION. The UNION examples don't help. There is no such thing as "converting an expression". Presumably you want to convert the integer result of evaluating some expression to the equivalent float. Union is just the ticket for this; in fact there doesn't seem to be any other way to do this.
cik@l.cc.purdue.edu (Herman Rubin) (01/08/88)
In general, you cannot change the type of a quantity (unfortunately). It may be that the problem can be avoided by using a cast when reading or writing the quantity, if the appropriate array is used. The 4.3 BSD VAX math library uses casts and #defines to set up the constants for the elementary functions. Otherwise your solution to use inline assembler statements is the only thing I have found to work, and the various gurus I have consulted have not come up with anything better. -- Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907 Phone: (317)494-6054 hrubin@l.cc.purdue.edu (ARPA or UUCP) or hrubin@purccvm.bitnet
roy@phri.UUCP (Roy Smith) (01/09/88)
[This really doesn't belong on unix.wizards; I've moved it to comp.lang.c] In article <11171@brl-adm.ARPA> weiser.pa@Xerox.COM writes: > I have a value which I happen to know has the proper bits to represent > a floating point number (either 32 or 64). However, it is of type int. > I would now like to tell the C compiler to treat this thing as a float. I think what you want to do is declare a union which has both int and float elements and use whever you prefer whenever you want. For example, the following program (compiled on a Sun-3, under SunOS-3.2) does what you want. Lint doesn't even complain (except about ignoring the value printf returns). Before you do this, however, be aware that this is not exactly what I would call portable code (although, as long as sizeof(int) >= sizeof(float), I don't see why it shouldn't work anywhere). Better than assembler in-lines, at any rate. main () { union {int i; float f;} x1, x2; int i; float f1, f2; f1 = 3.0; x1.f = f1; i = x1.i; /* i now has bit pattern for 3.0e0 */ printf ("%d\n", i); x2.i = i; f2 = x2.f; printf ("%f\n", f2); } alanine% cc test.c alanine% a.out 1077936128 3.000000 -- Roy Smith, {allegra,cmcl2,philabs}!phri!roy System Administrator, Public Health Research Institute 455 First Avenue, New York, NY 10016
jbuck@epimass.EPI.COM (Joe Buck) (01/09/88)
In article <11171@brl-adm.ARPA> weiser.pa@Xerox.COM writes: >I have the following problem: I have a value which I happen to know >has the proper bits to represent a floating point number (either 32 >or 64). However, it is of type int. I would now like to tell the C >compiler to treat this thing as a float. How can I do it without >taking the address of the thing (which may not have an address >because it is in a register or is an expression) or using a >subroutine call (for which I do not wish to pay the cost)? Casts are conversions. Because of the way they work with pointers on byte-addressible machines, many beginners seem to think that (type)x means to treat the bit pattern in x as if it were of type "type", but it most emphatically doesn't. But, we have unions to deal with this problem. If you have a machine in which both ints and floats have the same length, the following will work. union { int i_format; float f_format; } fubar; #define CONVERT(x) (fubar.i_format = (x), fubar.f_format) This is absolutely horrible and nonportable (it's not predictable if the lengths of ints and floats isn't the same), but it will work for your specific problem. -- - Joe Buck {uunet,ucbvax,sun,decwrl,<smart-site>}!epimass.epi.com!jbuck Old internet mailers: jbuck%epimass.epi.com@uunet.uu.net Argue for your limitations and you get to keep them. -- Richard Bach
anamaria@lll-lcc.llnl.GOV (Ana Maria De Alvare) (01/09/88)
I will consider using the UNION construction. Make a structure that has a union of an int and a float on the same space. That way you can name the same space with two different type. This is also machine dependent in the sense that you need to have the same bit length for both float and int types. Consult Kernigham and Ritchie's C Programming Language book. I have used it for bit and int unions and it makes it easier to manipulate the information. Example: union header { char byt_hdr[2]; struct { unsigned :2, f_dri :1, f_dpi :1, f_dp :1, f_dsn :3, :1, f_revw :3, f_rp :1, f_rsn :3; }flags; }; This will give you the chance of requesting the information on an array of characters or as the bits values itself of that array of character. Really is the word-size I am using on the array of character to retrieve all the bit information and in other parts of the program to manipulate the bits individually. Might sound cumbersome right now, but it does may life easy. See page 139 opn kernigham and Ritchie for more details. Ana Maria
wcs@ho95e.ATT.COM (Bill.Stewart) (01/09/88)
In article <11175@brl-adm.ARPA> weiser.pa@Xerox.COM writes:
:Sigh. I must not have made myself sufficiently clear. Before I get any more
:responses to my converting-to-float request, please note that I need to convert
:an EXPRESSION. The UNION examples don't help.
Declare the union somewhere within the scope you need (global if you
must), and use a comma operator if there's no cleaner way to express things.
union { int i; float f; } intfloat;
target = ( intfloat.i = messy()->expr , intfloat.f ) ;
Remember the parentheses around the comma expression.
I tried this, and lint didn't even mind.
--
# Thanks;
# Bill Stewart, AT&T Bell Labs 2G218, Holmdel NJ 1-201-949-0705 ihnp4!ho95c!wcs
mjh@uunet.uu.NET (Mark J. Hewitt) (01/12/88)
Mark, Methinks you are looking for an equivalent to Mesa's untyped LOOPHOLE conversion. I don't believe there is one in `C', no matter how you bend the rules, and I've been `C' programming for many years now. Originally Modula-2 only had casts (called type transfer functions there) of the `C' type, but the BSI/ISO standarisation group has been looking at `unsafe' conversions where only the bits are transferred. I can't see how this can be vendor independent as the representations of REAL types (both bit length and mantissa & exponent representations) are still (despite IEEE) quite variable. Sorry to be so negative, but hope to be proved wrong. Mark J. Hewitt usenet: ...!{mcvax,uunet,ukc}!kernel!mjh other: mjh%kernel.uucp@ukc.ac.uk voice: (+44) 532 465311 fax: (+44) 532 420183 paper: Kernel Technology Ltd, 21 Queen Street, Leeds, LS1 2TW, West Yorkshire, UK ------------------------------------------------------------------------------- What's the point of having opinions if they get ascribed to someone else? -------------------------------------------------------------------------------