Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28630 Discussions

TRANSFER function produces wrong result

afshar__yaser
Beginner
944 Views

(ifort version 16.0.1 on OSX L Capitan 10.11.3) using Transfer function in this version produces wrong results:

program test
implicit none
integer :: i
i=-2098177 
print*,i,transfer(i,1_8)
print'(b32.32,10x,b64.64)',i,transfer(i,1_8)
end program test
    -2098177              -2098177
11111111110111111111101111111111          1111111111111111111111111111111111111111110111111111101111111111

 

while using the older version (ifort version 15.0.2) produces the correct results

    -2098177           4292869119
11111111110111111111101111111111          0000000000000000000000000000000011111111110111111111101111111111

 

0 Kudos
1 Solution
mecej4
Honored Contributor III
944 Views

All the results that you listed are in agreement with the designation "processor dependent", and code that assumes a particular result is not portable code.

The next question is, "which result would most users want to see as a result of transferring a negative integer to a wider destination? In assembly language terms, after the source has been loaded into the EAX register, should we use a MOVZX or a MOVSX? Personally, I would like the sign to be preserved. As long as we are using 2-complement representation, I think that what IFort 16.0 is doing is preferable.

Let us see what others have to say.

View solution in original post

0 Kudos
7 Replies
mecej4
Honored Contributor III
944 Views

The Fortran standard says this about the TRANSFER intrinsic function:

If the physical representation of the result is longer than that of SOURCE, the physical representation of the leading part is that of SOURCE and the remainder is processor dependent.

I interpret "leading part" to mean "in little-endian byte order" rather than in "leading in printed text form".

0 Kudos
afshar__yaser
Beginner
944 Views

Yes, I agree with the standard, but this is not the case as the integer value is (-2098177). Plus there is the difference in intel FORTRAN versions as I mentioned.

This looks like a bug, not standard misinterpretation.

0 Kudos
mecej4
Honored Contributor III
944 Views

Please try -1 in place of -2098177 on line-4 of your test program, and reevaluate your expectations.

0 Kudos
afshar__yaser
Beginner
944 Views

Please look at this:

program test
implicit none
integer :: i
integer(8) :: j
i=-1 
j=transfer(i,1_8)
print*,i,j
end program test

(ifort version 16.0.1 on OSX L Capitan 10.11.3)

          -1                    -1

(ifort version 15.0.2)

          -1            4294967295

(gcc version 5.2.0)

          -1           4294967295

(ifort version 14.0.0)

          -1            4294967295

(pgfortran 15.9-0 64-bit target on x86-64 Linux)

           -1               4294967295

You can see the difference in intel versions also with other compilers. As if the transfer function in this new version is working like (INT(-1,8)).

 

0 Kudos
mecej4
Honored Contributor III
945 Views

All the results that you listed are in agreement with the designation "processor dependent", and code that assumes a particular result is not portable code.

The next question is, "which result would most users want to see as a result of transferring a negative integer to a wider destination? In assembly language terms, after the source has been loaded into the EAX register, should we use a MOVZX or a MOVSX? Personally, I would like the sign to be preserved. As long as we are using 2-complement representation, I think that what IFort 16.0 is doing is preferable.

Let us see what others have to say.

0 Kudos
Steven_L_Intel1
Employee
944 Views

The original answer holds - the result of what you are doing is "processor-dependent" which means that the implementation can do anything it wants. We have made changes in TRANSFER in the past and it may be that the way we handle this case changed. Both results are "correct" - one may be not what you want, but that's not a compiler bug.

We have an intrinsic function ZEXT that does the zero-extension, but it is non-standard. TRANSFER is not what you want for this purpose. 

0 Kudos
jimdempseyatthecove
Honored Contributor III
944 Views

>> should we use a MOVZX or a MOVSX? Personally, I would like the sign to be preserved

You can get sign preserved with

AnI8 = AnI4

If TRANSFER performs sign extension (which is not printed order by the way), then you do not have a means of performing unsigned extension. Which complicates performing multi-precision arithmetic without using a unioned structure of AnI8 and AnI4. Personally I use the UNION because it is unambiguous as to your intentions.

Jim Dempsey

0 Kudos
Reply