[2 days left] Whatâ€™s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
Solved

# Bitwise Operations on Single, Double or Decimal types ?

Posted on 1998-03-09
Medium Priority
516 Views
Is it possible to perform bitwise operations on types other than byte, integer or long ?

eg.

dim x as Double

x = 345678890 ' or any large number

? x And 2 ^ 60

This is currently resulting in an overflow.
0
Question by:woka
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 7
• 6

LVL 8

Expert Comment

ID: 1458736
You bet.

But you can't check for a bit that doesn't exist.  You must remember the size of the data type:

Byte = 8 bits
Integer = 16 bits
Long = 32 bits
Double = 64 bits

*** AND ***
When you're checking the sign bit of an integer or long - the bit value must be negative.  For example, to check bit 15 of an integer... Use the following:

If MyInt and 1(2^15) then
Msgbox "Bit is set"
else
Msgbox "Bit is clr"
endif

0

LVL 8

Expert Comment

ID: 1458737
Whoops, that last example should have been:

If MyInt and -(2^15) then
Â Â Msgbox "Bit is set"
else
Â Â Msgbox "Bit is clr"
endif
0

LVL 2

Author Comment

ID: 1458738
Given your answer, the example I gave should work.  Instead it results in an overflow error.  Any more ideas ?

0

LVL 8

Expert Comment

ID: 1458739
Sorry woka, the bit values of a floating type (double or single) are comprised of a sign bit, mantissa bits and exponent bits.  You really can only effectively test bit values of integers.

While Bit 60 exists, 2^60 is a larger value than a double can store precisely.  To answer your question, Bit 60 in the 64 bits that make up a double would have to be tested as follows:

If 2 ^ 28 And x Then
Print "Bit 60 is Set"
Else
Print "Bit 60 is Clr"
End If

0

LVL 2

Author Comment

ID: 1458740
Sorry to keep coming back about this (not sure if I should keep reopening the question either, is that the right protocol) but how did you derive the 28 in 2 ^ 28 ?

0

LVL 8

Accepted Solution

mrmick earned 800 total points
ID: 1458741
Whoops, I that was the 64th bit I set.  Here is example code that sets the 60th bit and displays the resulting number in the debug (immediate) window.  Create a new project and paste this code into the project.

'The eight bytes that make up a double
Private Type DoubleBytes
B0 As Byte
B1 As Byte
B2 As Byte
B3 As Byte
B4 As Byte
B5 As Byte
B6 As Byte
B7 As Byte
End Type

'A Double
Private Type MyDouble
dbl As Double
End Type

Dim db As DoubleBytes
Dim mydbl As MyDouble

'Set the 60th bit (range = 0 to 63)
db.B7 = 16

'Copy the bytes to the double.
LSet mydbl = db

'Display the result
Debug.Print mydbl.dbl

End Sub

0

LVL 2

Author Comment

ID: 1458742
Excellent !!  Thanks for your help with this, it's going to make my life a lot easier.  FYI, the application I am using it with is taking data from a UPS where each bit in a series of bytes represents an event.  There are a total of 74 possible events.  While I can use a UDT to manipulate the info, I also have to pass it using COM where UDT's are a no go.  Passing a variant containing a Decimal data type is a lot more practical than having to deal with a bunch of bytes or integers or longs (I've had a quick bash modifying your code and it doesn't really like me using a variant, but I'll find a way around this).

I spent some time last night pouring over some old fortran doco on IEEE formats but didn't really get anywhere.  The solution you've given me will help imensely (sp?).  Thanks again.

PS.  Isn't LSet a useful little thing !

0

LVL 8

Expert Comment

ID: 1458743
No problem, If you let me know how many bits are in your data type, I can probably show you an even easier way of passing the data.  Furthermore, you're best bet is to create a class to handle this.  I have an appointment right now (will take most of the evening), but when I return, If you've given me more details, I'll try to work out an example for you.  Give me an example of your call passing the data too.
0

LVL 2

Author Comment

ID: 1458744
I am planning on using a double or decimal data type.  In a variant, the doco states that double is 16 bytes and decimal is 12 or 14 bytes depending on where you look.  It would be nice to use a "normal" way of checking bits like:

if varDouble And &H4000000 then

but since this will (I suspect) result in overflow I suppose a series of functions as follows would work best:

varDecimal = SetBit(varDecimal as Variant, BitNumber as Integer, bSet as Boolean)

bSet = IsBitSet(varDecimal as Variant, BitNumber as Integer)

The variable (I've been using a variant with a long data type for testing) is already contained within a class (and collection) with all the other UPS data.  Is this what you meant ?

TIA

0

LVL 8

Expert Comment

ID: 1458745
I was going to carry it a bit further (no pun intended).  For example, if bits 0 - 5 indicated the Week of the Year, and bit 6 indicated AM or PM, I might expose the following properties:

'Class level array declaration.
Dim Bits(0 to 15) as byte â€˜Array of bytes containing 16 bytes of bits (128 bits)

Property Get WeekOfYear() As Long 'Could be Integer, or even Byte
DayOfWeek = Bits(0) And &H3F
End Property

Property Let DayOfWeek(NewValue As Long)
Bits(0) = (Bits(0) And &HC0) Or (NewValue And &H3f)
End Property

Property Get IsAM() As Boolean
IsAM = Bits(0) And &H40H
End Property

Property Let IsAm(NewValue as boolean)
Bits(0) = (Bits(0) And &HBF) Or (NewValue And &H40)
End Property

And so on...

I still have no idea what method youâ€™re using to pass the bit info so I canâ€™t make a suggestion.  If you posted the method youâ€™re using to pass the bit data, I would likely see a good solution to that problem.

0

LVL 2

Author Comment

ID: 1458746
This may need a bit of explanation.

The UPS is sending information to the PC (via a serial port) in ASCII packets.  There are several different types of packets containing different information, but the one I'm dealing with here is as follows:

Each 1 or 0 represents an event currently happening on the UPS. eg. The first 1 represents the event "Mains Failure".  If it is 1, the mains supply has failed and if it's 0 the mains is OK.

I'm just taking the ASCII string and storing it in a variable where each bit represents an event.

The method used to pass the info is like this:

Sub UpdateEvents(vEvents as Variant)

The variant would presumably be of type double or decimal.

Given that each bit is has an individual purpose rather than being combined with other bits, I'm not sure the method you have shown above is applicable.

Having said that, the penny has dropped with what you are doing and I can see a lot of applications for it that I wouldn't have thought to deal with that way before.  I obviously didn't write enough Fortran !

Am I on the right track ?  Let me know if you still think there is an application for what you presented above.  TIA.
0

LVL 8

Expert Comment

ID: 1458747
Hmmm... I think so (by the way, I haven't written any Fortran since 1982).  I think I'm going to put this to rest...  I didn't realize you were communicating through a serial port; I thought you were working with a DLL interface that handled communications with the UPS.  My mistake.

Until next time...
0

LVL 2

Author Comment

ID: 1458748
Thanks again for your input.  It's been really valuable, not to mention how quick your responses have been.
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone â€¦
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asseâ€¦
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). Uâ€¦
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process fromâ€¦
###### Suggested Courses
Course of the Month14 days, 15 hours left to enroll