- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to convert a FORTRAN code that was written many years ago on a Univac computer (36-bit) that I am assuming was running FORTRAN IV or FORTRAN Vto FORTRAN 90 (32- and 64-bit). There are two intrinsic functions the code uses that I can not seem to replicate in FORTRAN 90 and am looking for a workaround, if possible.
1) The "FLD" function. The inputs are as follows,
fld(start, number, variable)
start = starting bit in floating point word
number = number of bits to use
variable = floating point value
FORTRAN90 intrinsic, IBITS is close but the variable must be an integer. My variable is a real, floating point value. This is very important. It must be a real, not integer input.
2) Logical AND function.
I need to logically AND two values together. The first is a real, floating point value and the second will be input as a binary or hexidecimal value. FORTRAN 90 has the IAND intrinsic but again, the inputs must be integer. I need it to accept non-integer inputs.
The algorithm I am trying to write was written for extreme speed.
Any help would be greatly appreciated.
Thank you very much for your time.
Sincerely,
David
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
David,
The old 36-bit floating point format is bit size, bit field, and may not have the assumed always 1 characteristics of the REAL(4) and REAL(8) floating point formats used on PCs. This being the case, even if there were an FLD function in IVF the bit positions and extents used in your old code on 36-bit data would not function properly with the same arguments when used on REAL(4) and/or REAL(8) values. And there may be Little-Endian vs, Big-Endian issues too.
That said, if you have 36-bit packed binary data files that you must read/convert, then it may be more suitable to write a C/C++ function to perform the translation.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank ou for your quick reply. In reading your response, I think I was a bit vague on what I was asking. Let me give you more information. I am not trying to read old data but instead am trying to replicate the algorithm that was used years ago. I totally understand what was done and am trying to replicate it using FORTRAN 90 and their instrinsic functions. The issue is not 36 versus 32 (or 64) bit word sizes or Little/Big Endian, its more of, are their equivalent intrinsics that will allow me to do was done in a previous version of FORTRAN. The algorithm takes a real value and performs a function on this value where the algorithm uses the FLD and AND intrinsics. I can set the algorithm up for 32 and 64 bit word sizes but need the functionality of these intrinsics for it to work.
Now, you also mentioned C/C++. Are there intrinsics in C/C++ that will do this? If so, is it possible to embed C/C++ code within FORTRAN code to do this? I do not want to call a subroutine as this will add too much time to an extrememly fast algorithm that I am desparatly trying to replicate.
Thanks again for your help. It is greatly appreciated.
Sincerely,
David
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's difficult to imagine how performance could be enhanced by performing integer operations on sub-fields of floating point numbers. Compilers already did risky things automatically, like dividing or multiplying by 2 by integer arithmetic on the exponent field. A more likely reason for these bit field operations would be to pack multiple data into a 36-bit word, on account of the limited memory available on those machines, and lack of short integer data types.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
I am aware you are a strong proponent of using TRANSFER. However, to use a programmer's technical term, the documentation on TRANSFER really sucks. Or at least your statement that TRANSFER is similar to a "cast" operation. If you could provide some samples that clarify this it would be appreciated (then include the examples in the next go around for the documentation).
For example, I would like to "cast" a 3 diemensional array as a 1 dimensional array (note I do not wish for the "cast"to perform acopy)
If TRANSFER has any functionalitysimilar to "cast"I would be able to do something like
real,target :: A(nx, ny, nz)
AscalarValue = TRANSFER(A, ??, nx*ny*nz)(index)
Where ?? is something like (/0.0/) indicating real, nx*ny*nz indicates the size of the array, and (index) is a subscript of the RVALUE of the "cast" of the TRANSFER.
To me, a UNION or equivilance is much clearer.
Along the same subject
real,target, allocatable:: A(:,:,:)
real,pointer :: p_A(:)
How would one "cast" a one dimensionalpointer to all of A or part of A?
And while you are at it specify the base and extent for p_A?
I know I can coerce this by way of calling a subroutine with the starting cell within array A, then dimensioning the dummy in the subroutine approriatly then constructing the descriptor for use in => but this is a lot of hoop jumping for respecifying an array layout without having to perform a copy operation.
Any light you can shed on this would be greatly appreciated.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
>>Perhaps cast is not the right word, though it comes close. TRANSFER looks like a function that returns a result that has the same "bits" as the source but with the type and shape you specify in the other arguments. It is an expression and in Fortran an expression cannot be indexed.<<
Does TRANSFER (when remolding an array) produce an array descriptor?
i.e. can TRANSFER be used to generate an array descriptor for use on call to subroutine without performing a copy of the data to a temporary array?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I now realize that I left out an important aspect of TRANSFER. TRANSFER really does type conversion. While you can specify an array as MOLD, if you do the result is a one-dimensional array - the shape of the MOLD argument is ignored.
It might be that what you're looking for is RESHAPE to avoid making a source copy if your actual argument is a different shape than the corresponding dummy argument and the dummy is assumed shape. But RESHAPE will generally make a copy.
If the dummy is not assumed-shape, then you can pass the first element of the array and the rest of the array will be "sequence associated" with the dummy argument. For example:
integer a(10,5)
a = 0
print *, loc(a)
call sub(a(1,1))
contains
subroutine sub (a)
integer a(2,5,2)
print *, loc(a)
return
end subroutine sub
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
Thanks for your input on this.
I have been using CALL and dummy argument of different shape for years (decades) but I thought it would be nice if one could do the equivilent in-line with the code. A simple cast like operator would be nice.
The gen-interfaces/check-interfaces if strictly enforced would balk at the call reshaping.
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

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