Operating System - OpenVMS
1753286 Members
5601 Online
108792 Solutions
New Discussion юеВ

Convert IEEE float on Alpha to G_FLOAT doens't work with CVT$CONVERT_FLOAT

 
Mario Dhaenens
Frequent Advisor

Convert IEEE float on Alpha to G_FLOAT doens't work with CVT$CONVERT_FLOAT

On a Alpha server(VMS 8.3) I receive a FLOAT from an Application running on Integrity.
Before I process this on the Alpha server I have to convert this IEEE_FLOAT to a G_FLOAT.
I tried to use the routine below but it always crash with (-SYSTEM-F-FLTINV.
All help is welcome.

This is compiled with a Fortran compiler on Alpha using the default options(/FLOAT=G_FLOAT)

Example of the program.

REAL*8 CVT_FLOAT_IN
REAL*8 CVT_FLOAT_OUT
INTEGER*4 STATUS

STATUS=CVT$CONVERT_FLOAT(
CVT_FLOAT_IN, %VAL(CVT$K_IEEE_T),
CVT_FLOAT_OUT, %VAL(CVT$K_VAX_G),
%VAL(CVT$M_ROUND_TO_NEAREST))

Dump info:
%SYSTEM-F-HPARITH, high performance arithmetic trap, Imask=00000000, Fmask=00000001, summary=02, PC=0000000000053128, PS=0000001B
-SYSTEM-F-FLTINV, floating invalid operation, PC=0000000000053128, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs PC
AAN210 CONVERT_FLOAT CONVERT_FLOAT 90 00000000000000C8 0000000000053128
AAN210 AAN210$MAIN AAN210$MAIN 1166 0000000000000EAC 0000000000030EAC
PTHREAD$RTL 0 0000000000057618 FFFFFFFF81277618
PTHREAD$RTL 0 0000000000030444 FFFFFFFF81250444
0 FFFFFFFF8037DCE4 FFFFFFFF8037DCE4
%TRACE-I-END, end of TRACE stack dump
7 REPLIES 7
RBrown_1
Trusted Contributor

Re: Convert IEEE float on Alpha to G_FLOAT doens't work with CVT$CONVERT_FLOAT

From HELP/MESSAGE HPARITH, we see that "summary=02" means "an attempt was made to perform a floating arithmetic, conversion, or cmoparison operation, and one or more of the operand values was illegal."

My next step would be to display the input t-float and verify that it is the expected value and that is is a valid t-float.

Good luck.
Mike Kier
Valued Contributor

Re: Convert IEEE float on Alpha to G_FLOAT doens't work with CVT$CONVERT_FLOAT

I haven't tested, but could it be that CVT$M_ROUND_TO_NEAREST is listed for conversions *to* IEEE, not *from*?

From VMS Help> RTL CVT$ CVT$CONVERT_FLOAT ARG

CVT$M_ROUND_TO_NEAREST The default rounding option for conversions to IEEE data types. This IEEE Std. 754 rounding mode results in the representable output value nearest to the infinitely precise result. If the two nearest representable values are equally near, the one whose least significant bit is 0 is the result.

I suspect you might want

CVT$M_VAX_ROUNDING The default rounding option for conversions to non-IEEE data types. Performs "traditional" style rounding. This mode results in the representable output value nearest to the infinitely precise result. If the two nearest representable values are equally near, the output value is the closest to either positive infinity or negative infinity, depending on the sign of the input value.
Practice Random Acts of VMS Marketing
John Gillings
Honored Contributor

Re: Convert IEEE float on Alpha to G_FLOAT doens't work with CVT$CONVERT_FLOAT

Mario,

You have to be very careful when juggling objects of multiple floating point formats in the same module in compiled languages. Since you've compiled with /FLOAT=G_FLOAT, this statement is not true:

REAL*8 CVT_FLOAT_IN

because the object is actually IEEE format. Some valid IEEE values are invalid if interpreted as G_FLOAT.

Because the FORTRAN compiler has been told the object is G_FLOAT, and it can therefore perform operations on the object under the assumption that it contains a valid G_FLOAT bit pattern. If that assumption is broken, even something as simple as a MOVE can generate a FLTINV exception. Note that the failing PC is in your code, not in the RTL routine, so the problem isn't in CVT$CONVERT_FLOAT.

You should declare your "foreign" floating point object as untyped (in FORTRAN INTEGER of the correct size is probably the simplest choice). In your case the "foreign" one is IEEE because you've compiled as G_FLOAT. It's better to refer to the object by address, and use generic "move these bits" type operations than let the compiler use float type specific operations, (like "=").

It's possible that recent versions of FORTRAN have attributes that allow you to specify the float type of a specific variable. Check your documentation.

Bottom line here is "never lie to a compiler".
A crucible of informative mistakes
Mario Dhaenens
Frequent Advisor

Re: Convert IEEE float on Alpha to G_FLOAT doens't work with CVT$CONVERT_FLOAT

Hi John,

I understand what you mean. But what I don't understand how I could use the routine
CVT$CONVERT_FLOAT to convert from IEEE_FLOAT to G_FLOAT in a Fortran based application.

Can you give an example?
Or perhaps I shouldn't use CVT$CONVERT_FLOAT to convert IEEE_FLOAT to G_FLOAT and vice versa.

/Toine
John Gillings
Honored Contributor

Re: Convert IEEE float on Alpha to G_FLOAT doens't work with CVT$CONVERT_FLOAT

/Toine,

Yes you can use CVT$CONVERT_FLOAT, but exactly how depends on where the IEEE value comes from. For example, suppose we read a record from a file. Assume the record is declared as an array of 100 bytes, and the IEEE value starts at byte 20.

BYTE RECORD(100)
REAL*8 MY_FLOAT

INTEGER*4 STATUS


STATUS=CVT$CONVERT_FLOAT(
RECORD(20), %VAL(CVT$K_IEEE_T),
CVT_FLOAT_OUT, %VAL(CVT$K_VAX_G),
%VAL(CVT$M_ROUND_TO_NEAREST))

Since FORTRAN doesn't know those bytes in the record are floating data, it doesn't care about the bits, and won't attempt to perform any floating operations on it.

If you want to declare the record as a structure, instead of declaring the IEEE field as some kind of REAL type, use the same size INTEGER, or a BYTE array.

If you want a more specific answer, please let us know exactly how your variable CVT_FLOAT_IN gets a value.
A crucible of informative mistakes
Hoff
Honored Contributor

Re: Convert IEEE float on Alpha to G_FLOAT doens't work with CVT$CONVERT_FLOAT

Fortran does pointers now.

Use the pointer and target keywords?
Mario Dhaenens
Frequent Advisor

Re: Convert IEEE float on Alpha to G_FLOAT doens't work with CVT$CONVERT_FLOAT

Closed