Why does &h8000 = -32768

evanscamman

Registered User.
Local time
Today, 10:15
Joined
Feb 25, 2007
Messages
274
This doesn't make sense:

&h1000 =4096
&h2000 =8192
&h4000 =16384
&h8000 =-32768
&h10000 =65536
&h20000 =131072
&h40000 =262144
&h80000 =524288
&h100000 =1048576

Why the negative number mid sequence? Is this how all good hex momma's teach their children to count, or is it a bug?

Evan
 
Off the top of head, I know there's a bit reserved as a sign bit- if you turn it, the whole number is now negative.

Reading your list is confusing so gimme a min to sort this out.
 
Sorry, bout the confusing list.
i just fixed it - please refresh
 
Ayup, it's the negative bit.

Don't forget that hex is basically compressed representation of binary, so when you have &hXX (a nibble), you are representing the binary XXXXXXXX (8 bits or byte).

Therefore, when the first place of hex causes the first place of binary representation to be 1, then the whole number will be negative and we start to count backward. In that case, the first digit of hex number has to be greater than 8 to tigger that sign bit:
Code:
?&h5000
 20480 
?&h6000
 24576 
?&h7000
 28672 
?&h8000
-32768 
?&h9000
-28672 
?&hA000
-24576 
?&hB000
-20480 
?&hC000
-16384 
?&hD000
-12288 
?&hE000
-8192 
?&hF000
-4096

In all case where first digit of hex is greater than 8, the binary representation has a 1 in the first place, which tells us that the number is supposed to be a negative. Access doesn't really expose us to choose between signed representation (e.g. 7 bits for number data, 1 bit for sign) or unsigned (e.g. 8 bits for numbers, give us much more bigger magnitude but no way to store negative numbers).
 
Last edited:
All good computers in all good languages use the top bit as a negative bit for certain types. Makes math interesting sometimes, especially when you use boolean operators!
 
I'm new to the whole binary constants thing, but from what I understand, for the math to work out right, each constant should be assigned a number that is a power of 2. Hex, as you said, is basically compressed binary, so here is my list of constants. My intention is that all of these switches can be stored in one Long variable.

1st of all, on a basic level, am I going about this in an intelligent way, or is this bad programming?

2nd - note how I had to replace &h8000 with the base 10 equivalant. Does everybody have to do this, do people just skip that number (it's the only one that comes out negative), or is there another way to say it in hex. Or does it not matter that it's negative, because the math will function just fine anyways...

'Constants to Control Form Operation
Private Const IF_IsSubForm As Long = &H1
Private Const IF_LinkItem As Long = &H2
Private Const IF_LinkItemSubForm As Long = &H4
Private Const IF_PreviewItem As Long = &H8
Private Const IF_UpdateItem As Long = &H10
Private Const IF_LinkUOM As Long = &H20
Private Const IF_PreviewUOM As Long = &H40
Private Const IF_UpdateUOM As Long = &H80
Private Const IF_PreviewCode As Long = &H100
Private Const IF_UpdateCode As Long = &H200
Private Const IF_DblClickUpdate As Long = &H400
Private Const IF_EnterKeyUpdate As Long = &H800
Private Const IF_EscKeyCancel As Long = &H1000
Private Const IF_TabKeyExit As Long = &H2000
Private Const IF_HideOnCleanup As Long = &H4000
Private Const IF_DisableOnCleanup As Long = 32768
Private Const IF_ShowBorder As Long = &H10000
Private Const IF_HideStock As Long = &H20000
Private Const IF_HideLinks As Long = &H40000
Private Const IF_HideResetBtn As Long = &H80000
 
Well, the problem isn't with how you store the constant, but rather the data type. If you had a unsigned integer, that would be nonissue.

However, as I said, Access doesn't really expose you to all available data type used by the computer, and the Long data type is always signed. One work around is to use Enum data type instead of a bunch of const. This also gives you the benefit of intellisense.

(Drats, doesn't work as Enum still uses Long data type to store the collection.

If you have a negative number, does it mess up your formula?)
 
Last edited:
Ummm...if you're doing boolean math you don't need to worry about the "-" sign. If you're doing standard math, you don't need constants that are powers of 2.
 
That's true if we were to use the binary representation, but to be honest, I find Access scary in how it tries (too hard!) to hide up the details, showing us weird data that would be otherwise very simple task if we saw it directly. The case is that we can write hex numbers, but Access will store it as a base 10 number. Now, I'm a bit confused about whether a negative number will throw off everything off the track e.g. Access will try to add &H4000 + &H8000 + &H10000 = 49152 rather than correct 114688. Converting 49152 back to hex would translate into C000, quite different from expected value of 1C000. So unless I'm confused, the fact that Access will treat the 1st bit of a byte as a sign as a sign may screw up with boolean logic?
 
Access, and computers in general, store everything in binary, not decimal.

If you are using a long to keep track of a bunch of flags, it doesn't matter whether you "see" binary, hex, octal, or decimal on the screen. Fact is, they're all the same and you can still access the individual bits to see if they're set or not. This is the same concept Microsoft uses for it's constants.

The issue is how you access them. If you have a statement like:
Code:
if myvalue and IF_ShowBorder then
 DoShowBorderStuff
end if

it doesn't matter if myvalue is negative or not, since you are performing boolean algebra, not regular math. You can learn a lot by opening Window's calculator and putting it on "Scientific". Since Evan is only working with bits, it doesn't matter what the number looks like.
 
You are correct that this is just a representation of number, and we just need to know whether there is a bit toggled in a particular position. However, what I'm getting at is that Access *doesn't* do boolean math by default, we lost that bit as I showed in post above where there should be a "1C000" but ended up with a "C000"

Now, With Evan's case, I suspect we have to OR it to make sure that Access does the boolean math, not algebra math and end up with "1C000" even though Access looks at "1C000" and says it's 49152.

Did I get that right or am I getting myself into deeper end of quagmire? :)
 
+ and OR give the same results:

Code:
Sub test()
Dim x As Long
Dim y As Long
Dim z As Long
    y = IF_HideResetBtn
    Debug.Print y
    y = IF_HideOnCleanup + IF_DisableOnCleanup
    x = y And (IF_HideOnCleanup Or IF_DisableOnCleanup)
    z = IF_HideOnCleanup Or IF_DisableOnCleanup
    Debug.Print y
    Debug.Print x
    Debug.Print z
End Sub
 
....or and + give the same results....

I thought that you should never use + and always use OR when working with bits like this. Now I'm getting confused... :(
 
Can't test this right now, but off the top of head once again, you use OR because it's fail-safe. If you used + first time, its same result but doing it again, it screws up everything, whereas you can OR several time without screwing up other flags.
 
If you'll look at sample VB and C++ code that uses bits to define parameters, you'll find they use the "+" sign in the function call. Use the "AND" operator to decode.
 
It's very possible I'm just confused, but I did a test:

Code:
Dim x As Long
Dim y As Long

x = IF_DisableOnCleanup + IF_HideOnCleanup
y = x

Debug.Print x

x = x Or IF_DisableOnCleanup
y = y + IF_DisableOnCleanup

Debug.Print x
Debug.Print y

The result:
Code:
-16384 'The initial value for x and y
-16384 'The value of x after the Or operator
-49152 'The value of y after the + operator

Not quite same thing. I would imagine that in C++ or C#, they may be able to explicitly define the data type or overload the operator to perform boolean math instead of algebra math. VB (at least the classic VB) does not have that luxury.

While we're just talking representation of numbers, which is always same (just like French have their own language for same concepts), what I cannot get over is whether the different representation due to signing would cause boolean math to act weird.

After doing some experimentations, I think I see the problem:
Code:
debug.Print hex(-32768)
FFFF8000
debug.Print hex(32768)
8000

The thing is that if you try to use &h00008000, VBA tries to cheerily help you and throw out the leading zeros, giving you &h8000, which it would then convert into FFFF8000, which can be bad thing if there were more bit flags to the left of 8's position.


Evan, BTW- I took a look at my Enum as I knew I used that for bit flags and found out that I didn't bother with hex representation- I just entered my base 10 powers of 2 and it works fine with the boolean math.
 
Banana and George:

Thanks for the help and clarifications.

Banana - what you just said about Access trying to help and throwing out the leading zeros makes sense. I thought there was something illogical going on there.

Based on what has been said here, it looks like I'm safe to use it for binary operations and not worry about the sign, because that is just Access converting it back to base 10, and doesn't change the actual binary data.

Evan
 
I went ahead and used &H8000 even though it comes out as -32768 instead of 32768.

When I started having problems with bit flags evaluating to TRUE when I knew they were false, I substituted the base 10 equivalant of &H8000 (32768). Lo and behold, everything started working after that.

So it appears that the sign bit CAN create a problem with bit flag use.

Evan
 
Last edited:
Thanks for posting back! I was wondering about that one myself. This confirms my suspicions that sign bit may not produce desired result for the bit flag use.
 
i would think H8000 is a two byte number, and happens to be a negative

larger Hex values are probably stored in 4 bytes and so will be positive agian, until you reach their negative point, which will be quite large as they will be

65000 squared representations, or so ie +- 2billion

so is signed

by moving to
 

Users who are viewing this thread

Back
Top Bottom