Silverfrost Forums

Welcome to our forums

How split 8bytes number into two 4-bytes and combine back

26 Oct 2023 8:05 #30670

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

26 Oct 2023 9:39 #30671
 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
26 Oct 2023 5:59 #30672

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

27 Oct 2023 12:14 #30675

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

27 Oct 2023 9:55 #30676

Modern Fortran dudes should care about EQUIVALENCE being obsolete in F2018 😃

18 Nov 2023 1:47 #30754

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?

 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 integer4 and U and L integer2 ?

18 Nov 2023 2:07 #30755

'v = int(L,k)' does not do what you want, but equivalencing v to L,U would.

 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 32-bit and 3GB memory. I had to write an integer*8 function JLOC to replace calling LOC.

20 Nov 2023 10:41 #30763

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

 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 INTEGER4 and INTEGER8 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 REAL4 numbers) as i need then to convert integer U and L to real4 u and l

22 Nov 2023 5:39 #30766

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 ~1015 from 1e9 and paraphrasing Bill Gates 'The 1015 will fit to everyone until AI and Big Data come'

 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

22 Nov 2023 3:13 #30768

All Fortran integers are signed, so for INTEGER4 values greater than 2147483647, U and L must be changed to INTEGER8.

 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
24 Nov 2023 7:12 #30774

Thanks. But still failing with one more 2...

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
24 Nov 2023 7:48 #30775
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
24 Nov 2023 8:42 #30776

Looks like this works! Thanks Paul

Please login to reply.