HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Count bits in VBScript

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
countbitsvbscript

Problem

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

Solution

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

Code Snippets

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
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

Context

StackExchange Code Review Q#149408, answer score: 2

Revisions (0)

No revisions yet.