forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

OFFTOP: How this code works?

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General
View previous topic :: View next topic  
Author Message
DanRRight



Joined: 10 Mar 2008
Posts: 2816
Location: South Pole, Antarctica

PostPosted: Tue Aug 05, 2008 7:38 am    Post subject: OFFTOP: How this code works? Reply with quote

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
View user's profile Send private message
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Wed Aug 06, 2008 12:40 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
DanRRight



Joined: 10 Mar 2008
Posts: 2816
Location: South Pole, Antarctica

PostPosted: Thu Aug 07, 2008 8:14 am    Post subject: Reply with quote

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
View user's profile Send private message
IanLambley



Joined: 17 Dec 2006
Posts: 490
Location: Sunderland

PostPosted: Thu Aug 07, 2008 9:35 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
DanRRight



Joined: 10 Mar 2008
Posts: 2816
Location: South Pole, Antarctica

PostPosted: Thu Aug 07, 2008 10:59 pm    Post subject: Reply with quote

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 Embarassed
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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