- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First of all, does Intel Fortran have a package for doing unsigned arithmetic?
We can't unfortunately type integers as unsigned like in C++. I would like to avoid the problem of interfacing mixed languages if possible.
The reason I ask, is that I want to convert a series of bytes (integer*1) quantites into 32 bit integers, 4 at a time. They are to be treated as unsigned bytes, and packed little endian first. For example the four bytes 81 82 83 and 84 would be converted to: Z'84838281'
If I type them as integer*1, Fortran treats them as signed quantites, which would be wrong. I want a direct packing into the 32-bit words without any conversion. Of course, if they have the range z'00' to z'79' there is no problem, since those would all be positive sign anyway. But the bytes I want to convert have the full range z'00' to z'FF'
Any ideas?
Thanks; Tammy
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer*1 byte0, byte1, byte2, byte3
byte0 + 256*(byte1 + 256*(byte2 + 256*byte3)))
or any equivalent. You could check that all the operations are promoted to default integer, or show explicit promotion to integer*4 kind.
The resulting 32-bit integer would be treated as signed, with the sign being the sign of the high order byte.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer*1 byte0, byte1, byte2, byte3
byte0 + 256*(byte1 + 256*(byte2 + 256*byte3)))
Unfortunately, this only works ifALL of the above are between 0 and Z'7F' If any bytes are outside this range the answer will be incorrect. That was the first thing I tried.
For example, if the bytes are FF, 00 00 and 00, the compiler will promote -1 to Z'FFFFFFFF' but what we actually want isFF000000.
And using theEQUIVALENCE statement has the same problems, because the compiler does arithmetic conversion. I can't turn it off.
However, using the ISHFT and IOR statements looks promising. Does Fortran have a Swap BYTES library call?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
iand(byte0,z'ff') + 256*(iand(byte1,z'ff') + 256*(iand(byte2,z'ff') + 256*iand(byte3,z'ff'))))
iand() used this way works the same as the non-standard zext() intrinsic inherited from DEC Fortran.
Elemental Intrinsic Function (Generic): Extends an argument with zeros. This function is used primarily for bit-oriented operations. It cannot be passed as an actual argument.
Syntax
result = ZEXT (x [, kind])
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tammy,
Why not simply tell Fortran the data are characters?
If you are not performing math operations but simply moving the bytes about you shouldn't have a problem. Also, when you write the data, either write in binary or text with hex formatting.
I find it easiest to us UNIONs for polymorphic data
type C4I4
union
map
character :: C4(4)
end map
map
integer(4) :: I4
end map
end union
end type
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is not entirely clear to me what you're looking for. If it's to swap the byte order, you can use a series of IBITS calls or shifts and masks to construct the value. There is no "swap bytes" intrinsic. However, on I/O, there is the ability to read "big-endian" data and convert it on input to little-endian.
Tammy, can you elaborate on your application and what you want to do?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dr. Fortran;
We could not persuade the military guys to use IEEE storage formats, unfortunately.
I'm getting the series of bytes (4 at a time) in "little endian" order from an external file. They are data telemetry from a military gadget (Secret proprietary info). So let's say I get:
80 81 82 83 F3 F4 F5 F6 B7 B8 B9 BA FF FE FD FC.
What I want to end up with is:
83828180, F6F5F4F3, BAB9B8B7, and FCFDFEFF.
The inputs and outputs are unsigned integers, and the telemetry device is giving us a "raw" file, i.e. non-Fortran. So I have to use a DIRECT ACCESS to read it. The output probably should be integer*8 because otherwise it will treat the final result as a signed integer. Likewise, there is a pitfall with ZEXT() because the assignment operator tries to do a sign conversion. I think the ISHFT function also does a zero extension. I will experiment with those.
To bad the ranges aren't small enough to allow integer*4 conversions. I have the same problem with 2-byte integers, but probably the best approach can also be used there.
Thanks; Tammy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
BTW, I forgot to mention:
I can't type the inputs as character*1 because the compiler has strict limitations regarding type conversions. They generate fatal error messages.
At least I haven't yet found a way to bypass this particular limitation imposed by the compiler. But possibly I have overlooked something "cute" or "clever."
I'm willing to try any new ideas....
Hmmm - - - machine code anyone? At least it would be efficient........
Thanks; Tammy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer(4) mydata(4)
open (unit=1,file='mydata.dat',form='binary',convert='big_endian'),status='old')
do
read (1,end=99) mydata
write (*,'(4Z9.8)') mydata ! Shows the data is byteswaped
end do
99 continue
close (1)
end
The "convert='big_endian'" tells the I/O system to byteswap the data within each element of the array. "form='binary'" says to read the data as a bytestream. This could also be done with the F2003 feature of stream access.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You may be interested in this link, which is Michel Olagnon's implementation of unsigned arithmetic. He has made it available for use.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page