|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
DanRRight
Joined: 10 Mar 2008 Posts: 2818 Location: South Pole, Antarctica
|
Posted: Tue Aug 05, 2008 7:38 am Post subject: OFFTOP: How this code works? |
|
|
Saw the "cool" footnote signature in fortran usersgroups forum where the author encripted his email address by using this trick (compile and run this tiny bit of text as free format text with switch /free or give it a filename and use extension f95
> ftn95 filename.f95 /lgo )
Code: | write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/));end |
How make it produce arbitrary text?
Last edited by DanRRight on Thu Aug 07, 2008 10:32 pm; edited 1 time in total |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Wed Aug 06, 2008 12:40 pm Post subject: |
|
|
Dan
Conversion backwards and forward from text to numeric. One needs to have sufficient decimal precision in the real*8 constants to get back the exact text.
Ian
Code: |
implicit real*8 (a-h,o-z)
character*32 line
real*8 data(4),d1,d2,d3,d4
parameter (d1=0.10273509947368046661d+201, &
d2=0.85408779798164891182d+195, &
d3=0.20628313781195820562d+167, &
d4=0.14508301358256921522d-46)
!convert a 32 character line of text to a four element real*8 array
line='qwertyuiopasdfghjklzxcvbnm123456'
data=transfer(line,data,4)
print 1000,data
1000 format(e38.21)
!convert it back
print *,transfer(data,(/'x'/))
!from data statement
data(1) = d1
data(2) = d2
data(3) = d3
data(4) = d4
print *,transfer(data,(/'x'/))
!original example
write(*,*) transfer((/17.392111325966148d0+i*1.d-13,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/));end
|
|
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2818 Location: South Pole, Antarctica
|
Posted: Thu Aug 07, 2008 8:14 am Post subject: |
|
|
Something wrong is somewhere.... Here are first 4 lines this code produces
0.102735099473680466610+201
0.854087797981648911820+195
0.206283137811958205620+167
0.145083013582569215220E-46
Look at first three numbers carefully. What is this?
What transfer function does and how it works? |
|
Back to top |
|
|
IanLambley
Joined: 17 Dec 2006 Posts: 490 Location: Sunderland
|
Posted: Thu Aug 07, 2008 9:35 am Post subject: |
|
|
Dan,
It appears that the "E" format only provides four characters for the exponent, and hence when three digits are required, the E is lost. I'm not sure what this means for input written to a file and subsequently read back.
The tranfer simply moves the data as bytes between the two representations, in much the same way that the EQUIVALENCE statement did, see the additional code. In the old days (when I was a lad) Fortran did not have character data and numeric data was used instead, simply being read or printed using an alpha-numeric or hollerith format when it was to be interpreted as text. By default FTN95 does not permit this old ragged method.
Regards
Ian
Code: |
implicit real*8 (a-h,o-z)
character*32 line1,line2
real*8 data1(4),data2(4),d1,d2,d3,d4
parameter (d1=0.10273509947368046661d+201, &
d2=0.85408779798164891182d+195, &
d3=0.20628313781195820562d+167, &
d4=0.14508301358256921522d-46)
!convert a 32 character line of text to a four element real*8 array
line1='qwertyuiopasdfghjklzxcvbnm123456'
data1=transfer(line1,data1,4)
print *,'Original text data converted to real*8'
print 1000,data1
1000 format(e38.21)
!convert it back
print *,'Converted back to text from real*8'
print *,transfer(data1,(/'x'/))
!from data statement
data1(1) = d1
data1(2) = d2
data1(3) = d3
data1(4) = d4
print *,'Text derived from data statements'
print *,transfer(data1,(/'x'/))
print *,'Conversion to real*8 using old fashioned equivalence method'
!using equivalence method
do i=1,4
istart = (i-1)*8 + 1
iend = istart + 7
!convert eight byte lump from line1 to real*8 data
call equivalent_r8(line1(istart:iend),data2(i))
print 1000,data2(i)
! convert the real*8 data back to a text string in line2
call equivalent_text8(data2(i),line2(istart:iend))
enddo
print *,'Conversion back to text using old fashioned equivalence method'
print *,line2
!original example
print *,'Original example'
write(*,*) transfer((/17.392111325966148d0+i*1.d-13,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/))
end
Subroutine equivalent_r8(text,real8)
!specify an 8byte text string and obtain the byte for byte translation to an 8 byte real
character*8 text, text_in_sub
real*8 real8, real8_in_sub
!use equivalence to specify an 8byte storage location to be common to a real*8 and text string
equivalence (text_in_sub,real8_in_sub)
!put text into common area
text_in_sub = text
!take out real*8 from common area
real8 = real8_in_sub
end
Subroutine equivalent_text8(real8,text)
!specify an 8 byte real and obtain the byte for byte translation to an 8byte text string
character*8 text, text_in_sub
real*8 real8, real8_in_sub
!use equivalence to specify an 8byte storage location to be common to a real*8 and text string
equivalence (text_in_sub,real8_in_sub)
!put real*8 into common area
real8_in_sub = real8
!take out text from common area
text = text_in_sub
end
|
|
|
Back to top |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2818 Location: South Pole, Antarctica
|
Posted: Thu Aug 07, 2008 10:59 pm Post subject: |
|
|
Thanks, got it, tricky function, but useful
And meantime we seems revealed unbelievable FTN95 bug. Funny, nobody use real*8 numbers > 1.d+100 or <1.d-100 out here?
Interesting to check if it exists in FTN77 for DOS?!
My colleague ones found missing factor 1.5 in his code after writing two books describing the results of the code |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|