desj@idacrd.UUCP (David desJardins) (10/02/89)
Does anyone have any ideas on how one should go about converting an integer to the floating-point number with the same bit pattern? One frequently (well, occasionally) needs to do this to implement certain bit manipulations efficiently on Cray computers and other vector machines, and possibly on other architectures with fast floating-point but no fast shift (?). The best way I have found to do this in FORTRAN is to write INTEGER I REAL X X = OR (I, 0). (The Cray FORTRAN compiler optimizes out the trivial OR instruction.) It doesn't seem that there is any equally straightforward way to accomplish this in C. I don't want to involve pointers because the whole point is efficiency, and I expect that it will be very difficult for any compiler to optimize out the dereferences in something like int i; float x; * (int *) & x = i; to produce a single register-to-register transfer (or not even that). What I think is probably necessary is to define a real function of one integer argument, returning the same bit pattern as its input. Ultimately I would need to get Cray to incorporate it into their C compiler as an intrinsic function. Does anyone have any experience with such a thing, or a good idea of how these functions should be named? -- David desJardins
henry@utzoo.uucp (Henry Spencer) (10/08/89)
In article <475@idacrd.UUCP> desj@idacrd.UUCP (David desJardins) writes: > Does anyone have any ideas on how one should go about converting an >integer to the floating-point number with the same bit pattern? ... > It doesn't seem that there is any equally straightforward way to >accomplish this in C. I don't want to involve pointers ... You might try unions. This is one of the things they're good for, albeit in a very implementation-specific way. (Not a problem here, since the operation is inherently implementation-specific.) If your compiler won't put unions into registers, complain to your supplier. -- A bit of tolerance is worth a | Henry Spencer at U of Toronto Zoology megabyte of flaming. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
ok@cs.mu.oz.au (Richard O'Keefe) (10/08/89)
In article <475@idacrd.UUCP>, desj@idacrd.UUCP (David desJardins) writes: > Does anyone have any ideas on how one should go about converting an > integer to the floating-point number with the same bit pattern? union { long i; float x; } pun; pun.i = the_integer_to_be_converted; the_single_precision_result = pun.f; > One frequently (well, occasionally) needs to do this to implement certain > bit manipulations efficiently on Cray computers and other vector machines ... Just which operations are these? If the operations are meaningful functions of floating-point numbers (e.g. things like ilogb() copysign() nextafter()) it might make more sense to ask Cray to put _those_ in their library. I really would like to know what the operations are.
bright@Data-IO.COM (Walter Bright) (10/10/89)
In article <475@idacrd.UUCP> desj@idacrd.UUCP (David desJardins) writes:
< Does anyone have any ideas on how one should go about converting an
<integer to the floating-point number with the same bit pattern?
Try a union:
union blah { int i; float f; } x;
x.f = f;
/* now manipulate x.i */
< It doesn't seem that there is any equally straightforward way to
<accomplish this in C. I don't want to involve pointers because the
<whole point is efficiency, and I expect that it will be very difficult
<for any compiler to optimize out the dereferences in something like
< int i;
< float x;
< * (int *) & x = i;
<to produce a single register-to-register transfer (or not even that).
Not at all. It's a pretty much standard and trivial optimization to
convert *(int*)&x=i into MOV X,I. Feel free to use it, with the caveat
that float format is not the same from machine to machine. I've done
it many times to do special manipulations on doubles.
jerry@violet.berkeley.edu ( Jerry Berkman ) (10/11/89)
In article <475@idacrd.UUCP> desj@idacrd.UUCP (David desJardins) writes: > Does anyone have any ideas on how one should go about converting an >integer to the floating-point number with the same bit pattern? >The best way I have found to do this in FORTRAN is to write > INTEGER I > REAL X > X = OR (I, 0). >(The Cray FORTRAN compiler optimizes out the trivial OR instruction.) > -- David desJardins Why not use equivalence? INTEGER I REAL X, IX EQUIVALENCE (X,IX) IX = I The Fortran standard specifies that a REAL and INTEGER occupy the same space. The only problem is this might fool some optimizers. - Jerry Berkman jerry@violet.berkeley.edu
ok@cs.mu.oz.au (Richard O'Keefe) (10/11/89)
In article <1989Oct10.185851.6490@agate.berkeley.edu>, jerry@violet.berkeley.edu ( Jerry Berkman ) writes: : In article <475@idacrd.UUCP> desj@idacrd.UUCP (David desJardins) writes: : > Does anyone have any ideas on how one should go about converting an : >integer to the floating-point number with the same bit pattern? : Why not use equivalence? : INTEGER I : REAL X, IX : EQUIVALENCE (X,IX) Because he was asking how to do it in C. I understand that the original problem was something that could be expressed quite clearly and simply as an ordinary C arithmetic expression operating exclusively on integers, and that straightforward C code would _work_ on the Cray, but because some operation (bitwise shifts?) didn't have a vector equivalent it wouldn't vectorise. But a hairy hack involving floats _would_ vectorise because the Cray system is good at vectorising float operations. The interesting point here is that there are a lot of things you can do IF you have the functions required and recommended in the IEEE 754 standard. For example, if there is some reason why you want to avoid p << i use (int) scalb((float)p, i) p >> j use (int) scalb((float)p, -j) This is why I think that it would be interesting for people with such problems (and this includes Herman Rubin) to give us more detail about the problem they are really trying to solve (e.g. the original poster's problem was "how do I get results equal to these in a way that will vectorise on a Cray?"). It may be that some of these problems have solutions which are less machine-specific than hand-crafted bit-twiddling, or would be if functional equivalents of the IEEE functions were provided.
exspes@gdr.bath.ac.uk (P E Smee) (10/11/89)
In article <1989Oct10.185851.6490@agate.berkeley.edu> jerry@violet.berkeley.edu ( Jerry Berkman ) writes: > >Why not use equivalence? > INTEGER I > REAL X, IX > EQUIVALENCE (X,IX) > > IX = I >The Fortran standard specifies that a REAL and INTEGER occupy the same space. >The only problem is this might fool some optimizers. > Problem is, the Fortran standard *also* says that if your program tries to take the value of the variable using a different type than the type you used when you last stored into it, your program is invalid. This is a polite way of saying (to the user) 'this trick may not work', and (to the compiler writer) 'your optimizer does not have to worry about aliasing between variables of different types'. If the compiler can tell that you are going to (e.g.) store an integer into that storage, and then read a real, it is under no obligation to make sure that the integer value gets stored. Fortran equivalence was designed toallow reuse of storage on the early small memory machines -- not to allow type punning. Usually you can get away with punning, but it doesn't always work and so is a bad habit. -- Paul Smee | JANET: Smee@uk.ac.bristol Computer Centre | BITNET: Smee%uk.ac.bristol@ukacrl.bitnet University of Bristol | Internet: Smee%uk.ac.bristol@nsfnet-relay.ac.uk (Phone: +44 272 303132) | UUCP: ...!mcvax!ukc!gdr.bath.ac.uk!exspes
khb%chiba@Sun.COM (Keith Bierman - SPD Advanced Languages) (10/13/89)
In article <1989Oct11.091619.18336@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes: >Problem is, the Fortran standard *also* says that if your program tries >to take the value of the variable using a different type than the type you >used when you last stored into it, your program is invalid. This is a >polite way of saying (to the user) 'this trick may not work', and (to >the My quick peek into the document (pages 8-3 and 17-1..4ish) doesn't make this obvious to me. Could you please quote chapter and verse ? > >Fortran equivalence was designed toallow reuse of storage on the early >small memory machines -- not to allow type punning. Usually you can >get away with punning, but it doesn't always work and so is a bad habit. > On which systems (if any) have you seen this not work ? Keith H. Bierman |*My thoughts are my own. !! kbierman@sun.com It's Not My Fault | MTS --Only my work belongs to Sun* I Voted for Bill & | Advanced Languages/Floating Point Group Opus | "When the going gets Weird .. the Weird turn PRO"
exspes@gdr.bath.ac.uk (P E Smee) (10/16/89)
In article <126279@sun.Eng.Sun.COM> khb@sun.UUCP (Keith Bierman - SPD Advanced Languages) writes: >In article <1989Oct11.091619.18336@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes: > > >>Problem is, the Fortran standard *also* says that if your program tries >>to take the value of the variable using a different type than the type you >>used when you last stored into it, your program is invalid. > >My quick peek into the document (pages 8-3 and 17-1..4ish) doesn't >make this obvious to me. Could you please quote chapter and verse ? > Section 17.3(2) -- (or, page 17.4, lines 15-18) 'When an entity of a given type becomes defined, all totally associated entities of different type become undefined.' With 17.2(1) 'Execution of an arithmetic, logical, or character assignment statement causes the entity that precedes the equals to become defined. These must, of course, be taken in conjunction with the definition of what it means for something to be defined, and with the fact that if your program uses variables while they are undefined, your program is invalid. From 17.1 it is clear that EQUIVALENCE may cause total association. May also cause only partial association depending on what the equivalanced entities are. In particular, from 17.1.1 single (non-array) integer, real, and logical values equivalenced in any mix are totally associated. >> >>Fortran equivalence was designed toallow reuse of storage on the early >>small memory machines -- not to allow type punning. Usually you can >>get away with punning, but it doesn't always work and so is a bad habit. >> > >On which systems (if any) have you seen this not work ? > Honeywell Multics at certain optimisation levels. Of course, since HIS don't make them any more, that's a moot point. I believe I recall similar occasional problems under various flavours of IBM OSes, again at particular optimisation levels. Doesn't alter the fact that since the standard makes it clear that it can be invalid, it's a bad habit. -- Paul Smee | JANET: Smee@uk.ac.bristol Computer Centre | BITNET: Smee%uk.ac.bristol@ukacrl.bitnet University of Bristol | Internet: Smee%uk.ac.bristol@nsfnet-relay.ac.uk (Phone: +44 272 303132) | UUCP: ...!mcvax!ukc!gdr.bath.ac.uk!exspes
exspes@gdr.bath.ac.uk (P E Smee) (10/16/89)
In article <1989Oct16.092936.142@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes: >In article <126279@sun.Eng.Sun.COM> khb@sun.UUCP (Keith Bierman - SPD Advanced Languages) writes: >>In article <1989Oct11.091619.18336@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes: >> >> >>>Problem is, the Fortran standard *also* says that if your program tries >>>to take the value of the variable using a different type than the type you >>>used when you last stored into it, your program is invalid. >> >>My quick peek into the document (pages 8-3 and 17-1..4ish) doesn't >>make this obvious to me. Could you please quote chapter and verse ? >> In the previous posting, I quoted chapter and verse from the 77 FORTRAN standard. The 66 standard is even stricter. EQUIVALENCE causes things to become associated (full stop -- no fudging about partial or total association) and says in 10.2.3.1 (5) [Variables and array elements become undefined as follows:] When an associated entry of different type becomes defined. So, I'd say the 66 standard prohibits it completely, while the 77 standard allows it in some cases (but only when the variables are not (loosely speaking) of the same size). The one interesting case which is explicitly valid in 77 appears to be EQUIVALENCE of a REAL array of dimension 2 with an COMPLEX variable, in which case REAL(1) would be the real part of the COMPLEX and REAL(2) the imaginary part. -- Paul Smee | JANET: Smee@uk.ac.bristol Computer Centre | BITNET: Smee%uk.ac.bristol@ukacrl.bitnet University of Bristol | Internet: Smee%uk.ac.bristol@nsfnet-relay.ac.uk (Phone: +44 272 303132) | UUCP: ...!mcvax!ukc!gdr.bath.ac.uk!exspes