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

Store information in the least significant bit?

Vishnu
Novice
448 Views

Say I use arrays of double precison REALs. If it is the case that I do not need all the precision it offers, (but of course more than single precision), then couldn't I use, say the least significant bit to store some boolean information? Do you guys see any flaw in the idea?

If I do this, I could avoid allocation all the memory corresponding that arrays of LOGICAL data would take up. If the effort to mantain and retrieve this data in the least significant bit is worth the memory saved, it may be useful in some situations.

Now, if I had to implement this, how would I go about it? I see lost of bit-wise manipulations for INTEGERs, but is there any way that I can modify bits (in particular, the least significant bit) in a REAL?

0 Kudos
6 Replies
TimP
Honored Contributor III
448 Views

You might use transfer or the like with masking.  Every time you store a new double precision value you would need to first save then replace your low order bit. It would not be portable across changes in byte storage order. Such tactics were more common 3 decades ago.

0 Kudos
mecej4
Honored Contributor III
448 Views

You would invite a load of trouble by employing parasitic brooding (e.g., some species of cuckoo laying eggs in the nests of other birds). 

If you treated bit-0 of an 8-byte real as a boolean, the resulting composite variable (structure variable) would not have any rules specified for performing arithmetic. If the processor performs standard real number, finite-precision, arithmetic on such variables, your boolean bits are going to be trashed. If you avoid such trashing by not doing real number arithmetic, you do not need real variables. For instance, if 4-byte precision is sufficient, declare a derived type with one REAL and one LOGICAL component instead of using an 8-byte real and trying to give special treatment to its least significant bit or bits.

As it is, floating point format has a defined set of zones: the leading bit (bit-63) is the sign of the number, the next 11 bits contained a biased exponent, etc. The floating point instructions of the processor know about these zones and produce results that fit into the appropriate zones. Adulterating the zones by appropriating pieces of them for other purposes is simply unworkable.

Note, furthermore, that in Fortran a LOGICAL variables are not represented by a single bit, nor can you mix LOGICAL and INTEGER variables indiscriminately.

0 Kudos
Vishnu
Novice
448 Views

Tim P. wrote:

You might use transfer or the like with masking.

Do you mean this ? If so, how exactly do I use it? Do I transfer the REAL source onto a LOGICAL mould? That just seems to give me .TRUE. no matter what number I use; what does that mean? Is it looking at bit-0?

Tim P. wrote:

Every time you store a new double precision value you would need to first save then replace your low order bit.

Yep; if I do use it, that is how it will be. This will be the cost of using this method, and I will have to weigh it with the advantage.

Tim P. wrote:

It would not be portable across changes in byte storage order.

What does that mean? Do you mean Endianess? If so, I will always run this on the machine I compile it on, so then I'll be safe, won't I?

Tim P. wrote:

Such tactics were more common 3 decades ago.

Any reason other than memory becoming cheap, for this to have gone out of use? Is it inherently unsafe in any way?

0 Kudos
Vishnu
Novice
448 Views

mecej4 wrote:

f you treated bit-0 of an 8-byte real as a boolean, the resulting composite variable (structure variable) would not have any rules specified for performing arithmetic. If the processor performs standard real number, finite-precision, arithmetic on such variables, your boolean bits are going to be trashed. If you avoid such trashing by not doing real number arithmetic, you do not need real variables. For instance, if 4-byte precision is sufficient, declare a derived type with one REAL and one LOGICAL component instead of using an 8-byte real and trying to give special treatment to its least significant bit or bits.

I intend to use it like Tim suggests; also, I can have almost-double precision with minimal extra memory cost (but possible some extra computational steps).

mecej4 wrote:

As it is, floating point format has a defined set of zones: the leading bit (bit-63) is the sign of the number, the next 11 bits contained a biased exponent, etc. The floating point instructions of the processor know about these zones and produce results that fit into the appropriate zones. Adulterating the zones by appropriating pieces of them for other purposes is simply unworkable.

Note, furthermore, that in Fortran a LOGICAL variables are not represented by a single bit, nor can you mix LOGICAL and INTEGER variables indiscriminately.

Yes, I know that; all computations with that data will proceed like it were a REAL array, and the temporary storage would be of LOGICAL type.

0 Kudos
mecej4
Honored Contributor III
448 Views

Vishnu wrote:
I intend to use it like Tim suggests; also, I can have almost-double precision with minimal extra memory cost (but possible some extra computational steps).

I don't see how. You are going to have only single-precision while consuming the same amount of memory as having the REAL and LOGICAL variables separate, and you are going to be writing a lot of extra bookkeeping code with nothing to show in return. Try the following example, and show us how you can modify it to do the things that you aim to do.

program xyz
implicit none
double precision x
logical l
integer i(2)
equivalence(i,x,l)
!
x=4*atan(1d0)
write(*,*)x
write(*,10)i(2),i(1)
l=.true.
write(*,10)i(2),i(1)
l=.false.
write(*,10)i(2),i(1)
10 format(1x,Z8.8,1x,Z8.8)
write(*,*)x
end program

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
448 Views

Are you really that tight on memory?

An alternate choice, if the exponent is not overly large, would be to bung-up (place the bit in) the exponent. This would preserve the precision at the expense of having very large/small exponents. As mecej4 cautioned, you would have to assure you remove the flag prior to operating on the variable.

Note, the computation cost of bit diddling will be severe as compared with using a separate array of logicals. Only very specific situations might yield a faster solution.

Careful, messing with the exponent may interfere with NaN's (choose carefully).

Jim Dempsey

0 Kudos
Reply