7
\$\begingroup\$

I'm trying to write a function that returns the number of bits set in a 32-bit integer in VBScript, it's just for practising the language. The function I've written so far looks okay, but I'm wondering if there was a simpler solution.

Function countBits(value)
 Dim n : n = 0
 Dim mask : mask = 1
 Dim i
 For i = 0 to 30
 If (value And mask) > 0 Then
 n = n +1
 End If
 Next
 If (value And &h8000) then
 n = n+1
 End If
 countBits = n
End Function

I found that there are no shift operators in VBScript and an overflow (Err.Number = 6) if I iterate for 0 to 31, that's why I add the explicitly check of the MSB after the look.

Any solutions to improve (maybe generalize) this?


edit: removed the useless error handling part, as it's a remains of starting with 31 as an upper bound in the first (and at that time only) loop

pacmaninbw
26.2k13 gold badges47 silver badges113 bronze badges
asked Dec 9, 2016 at 14:18
\$\endgroup\$
2
  • \$\begingroup\$ Please do not edit the question, especially the code, after an answer has been posted. Changing the question may cause answer invalidation. Everyone needs to be able to see what the reviewer was referring to. What to do after the question has been answered. \$\endgroup\$ Commented Jun 23 at 11:33
  • \$\begingroup\$ Thanks @pacmaninbw for the clarification. I only edited because my former editing mistake was not subject of the actual question. And also the answer only slightly touches this fact in a code comment... \$\endgroup\$ Commented Jun 23 at 13:05

1 Answer 1

5
\$\begingroup\$

According to information in VBScript Data Types MSDN article, a 32-bit integer is long variant subtype.

However, the value &h8000 (decimal -32768) seems to be a 16-bit integer minimal value; it's hexadecimal &hFFFF8000 if converted to long subtype (check Wscript.Echo Hex(&h8000).

This means that your function miscounts 1 additional bit for all long values above 32767 i.e. above 16-bit integer maximal value &h7FFF.

To check the sign bit of a long value correctly, use &h80000000 as follows:

Function countBits(value)
 Dim mask : mask = 1
 Dim i
 countBits = 0 ' no need to use any auxiliary variable
 For i = 0 to 30
 If ( value And mask ) > 0 Then
 countBits = countBits + 1
 End If
 mask = mask * 2 ' got lost due to your own edit Dec 11 '16 at 14:22
 Next
 If ( value And &h80000000 ) Then ' check the sign bit
 countBits = countBits + 1
 End If
End Function

Sample tests:

Wscript.Echo countBits(2^16) ' 1
Wscript.Echo countBits(2^30) ' 1
Wscript.Echo countBits(1) ' 1
Wscript.Echo countBits(-1) ' 32
Wscript.Echo countBits(-2) ' 31
Wscript.Echo countBits(-2147483648) ' 1
answered Jul 31, 2017 at 10:24
\$\endgroup\$
2
  • \$\begingroup\$ thanks so much sometimes I seem to be so blind for some important details, the off-by-one syndrome has so many faces this time I was off by one chunk of hexadecimal places. \$\endgroup\$ Commented Jul 31, 2017 at 14:46
  • 1
    \$\begingroup\$ Again, thanks, only now I realize the error I introduced by my first edit, fixed. \$\endgroup\$ Commented Jun 23 at 10:50

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.