
forums.silverfrost.com Welcome to the Silverfrost forums

View previous topic :: View next topic 
Author 
Message 
DanRRight
Joined: 10 Mar 2008 Posts: 2866 Location: South Pole, Antarctica

Posted: Thu Oct 26, 2023 9:05 am Post subject: How split 8bytes number into two 4bytes and combine back 


Is there some generally used way to split 8bytes number into two 4byte ones and then combine these two back to 8bytes all with minimal efforts? 

Back to top 


PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8017 Location: Salford, UK

Posted: Thu Oct 26, 2023 10:39 am Post subject: 


Code:  integer,parameter::k=4
integer(k) v
integer U,L
v = 17_k + ishft(27_k, 32)
print*,v
U = ishft(v, 32)
L = iand(v, Z'00000000ffffffff')
v = int(L,k) + ishft(int(U,k),32)
print*,L,U
print*,v



Back to top 


DanRRight
Joined: 10 Mar 2008 Posts: 2866 Location: South Pole, Antarctica

Posted: Thu Oct 26, 2023 6:59 pm Post subject: 


Thanks Paul, great, that kind of binary trickery I was exactly hoping for. 

Back to top 


JohnCampbell
Joined: 16 Feb 2006 Posts: 2584 Location: Sydney

Posted: Fri Oct 27, 2023 1:14 am Post subject: 


Dan, You can always use EQUIVALENCE, or TRANSFER if you are a modern Fortran dude! 

Back to top 


DanRRight
Joined: 10 Mar 2008 Posts: 2866 Location: South Pole, Antarctica

Posted: Fri Oct 27, 2023 10:55 am Post subject: 


Modern Fortran dudes should care about EQUIVALENCE being obsolete in F2018 

Back to top 


DanRRight
Joined: 10 Mar 2008 Posts: 2866 Location: South Pole, Antarctica

Posted: Sat Nov 18, 2023 2:47 pm Post subject: 


Paul,
Something is strange here. Let's take integer*8 numbers v larger than approximately 2 billion. After splitting them into pair of U and L and then combining back, these numbers are not getting back into itself
Where i am wrong?
Code: 
integer,parameter::k=4
integer(k) v
integer U,L
v = 2222222222_4
print*, v
U = ishft(v, 32)
L = iand(v, Z'00000000ffffffff')
print*,L,U
! getting v back
v = int(L,k) + ishft(int(U,k),32)
print*,v
end

By the way how will look this code for v being integer*4 and U and L integer*2 ? 

Back to top 


JohnCampbell
Joined: 16 Feb 2006 Posts: 2584 Location: Sydney

Posted: Sat Nov 18, 2023 3:07 pm Post subject: 


"v = int(L,k)" does not do what you want, but equivalencing v to L,U would.
Code:  integer,parameter::k=4
integer(4) v
integer U,L
common /aa/ L, U
equivalence (v,L)
v = 2222222222_4
print*, v
print*,L,U
U = 0
print*,v
print*,L,U
end 
Reminds me of the problem using LOC (aaa) with 32bit and 3GB memory. I had to write an integer*8 function JLOC to replace calling LOC. 

Back to top 


DanRRight
Joined: 10 Mar 2008 Posts: 2866 Location: South Pole, Antarctica

Posted: Mon Nov 20, 2023 11:41 pm Post subject: 


Looks like Paul's code either has an error or its functions have a bug or something is incorrectly used somewhere.
Anyone spotting the error in all that bits manipulations?
For the Integer*4 v the code modified as below works fine
Code:  integer,parameter::k=3
integer v
integer U,L
111 READ(*,*) v
U = ishft(v, 16)
L = iand(v, Z'0000ffff')
print*,L,U
! getting v back
v = int(L,k) + ishft(int(U,k),16)
print*,v
goto 111
end 
That allows to use v < 2 billion.
But that limitation on v is a bit too small.
So may be arbitrary precision between INTEGER*4 and INTEGER*8 will work? Because out of the box the U and L these v numbers generate have to be smaller than ~20 million (to be precise  below numbers represented by number of bytes in mantissa of REAL*4 numbers) as i need then to convert integer U and L to real*4 u and l 

Back to top 


DanRRight
Joined: 10 Mar 2008 Posts: 2866 Location: South Pole, Antarctica

Posted: Wed Nov 22, 2023 6:39 am Post subject: 


UPDATE,
despite errors with 8byte integers, with smaller v integers like 5 and 6 bytes this still works OK
I think this will work for me: V will be restricted to ~10^15 from 1e9 and paraphrasing Bill Gates "The 10^15 will fit to everyone until AI and Big Data come"
Code:  integer,parameter::k=4
integer(4) v
integer U,L
111 READ(*,*) v
U = ishft(v, 24)
L = iand(v, Z'000000ffffff')
print*,L,U
! getting v back
v = int(L,k) + ishft(int(U,k),24)
print*,v
goto 111
end 
/* V is how many cells or particles you allow in your numerical codes. Of course with integer*8 you can get 10^18 but this will require to increase file sizes twice 

Back to top 


PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8017 Location: Salford, UK

Posted: Wed Nov 22, 2023 4:13 pm Post subject: 


All Fortran integers are signed, so for INTEGER*4 values greater than 2147483647, U and L must be changed to INTEGER*8.
Code:  integer,parameter::k=4
integer(k)::v,U,L
v = 2222222222_k
U = ishft(v, 32)
L = iand(v, Z'00000000ffffffff')
v = int(L,k) + ishft(int(U,k),32)
print*,L,U,v
end 


Back to top 


DanRRight
Joined: 10 Mar 2008 Posts: 2866 Location: South Pole, Antarctica

Posted: Fri Nov 24, 2023 8:12 am Post subject: 


Thanks.
But still failing with one more 2...
Code:  integer,parameter::k=4
integer(k)::v,U,L
v = 22222222222_k
U = ishft(v, 32)
L = iand(v, Z'00000000ffffffff')
v = int(L,k) + ishft(int(U,k),32)
print*,L,U,v
end 


Back to top 


PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8017 Location: Salford, UK

Posted: Fri Nov 24, 2023 8:48 am Post subject: 


Code:  integer,parameter::k=selected_int_kind(18)
integer(k)::v,U,L
v = 22222222222_k
U = ishft(v, 32)
L = iand(v, Z'00000000ffffffff'_k)
v = ior(L,ishft(U,32))
print*,L,U,v
end



Back to top 


DanRRight
Joined: 10 Mar 2008 Posts: 2866 Location: South Pole, Antarctica

Posted: Fri Nov 24, 2023 9:42 am Post subject: 


Looks like this works! Thanks Paul 

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
