Issues Implementing Halstead's Complexity Metrics

1.8k views Asked by At

I'm currently practicing with a simple program to understand the equations involved in deriving various metrics from Halstead's software science. I do believe I'm doing it correctly, but I feel like I haven't registered all operands and operators so that I can start with the mathematics.

The program I'm using is:

/*01*/ // counts how many items in sArray[] are also in tArray[]
/*02*/ int matched(int sArray[], int tArray[], int sMax, int tMax)
/*03*/ {
/*04*/    int count, i, first, middle, last;
/*05*/ 
/*06*/    for (i = 0; i < sMax; ++i)
/*07*/    {
/*08*/        last = tMax - 1;
/*09*/        for (int first = 0; first <= last;)
/*10*/        {
/*11*/            middle = (first + last) / 2;
/*12*/            if (tArray[middle] == sArray[i])
/*13*/            {
/*14*/                 count++;
/*15*/                 break;
/*16*/            } 
/*17*/            if (tArray[middle] < sArray[i]) 
/*18*/            {
/*19*/                 first = middle + 1;
/*20*/            }
/*21*/            else
/*22*/            {
/*23*/                 last =  middle - 1;
/*24*/            }
/*25*/         }
/*26*/    }
/*27*/    return count;
/*28*/ }

And I've come out with

  • n1 = the number of distinct operators = 10
  • n2 = the number of distinct operands = 9
  • N1 = the total number of operators = 24
  • N2 = the total number of operands = 34

These notes show the distinct operators and operands found:

Operators
= Assignment (line 6, 8, 9, 11, 19, 23) = 6
< Less Than (line 6, 17) = 2
++ Increment (line 6, 14) = 2
- Subtract (line 8, 23) = 2
<= Less Than or Equal to (line 9) = 1
+ Addition (line 11, 19) = 2
/ Division (line 11) = 1
== Equal to (line 12) = 1
[] index (line 2*2, 12*2, 17*2 = 6
break (line 15) = 1

Operands
count (line 4, 14) = 2
i (line 4, 6*3, 12, 17) = 6
first (line 4, 9*2, 11, 19) = 5
middle (line 4, 11, 12, 17, 19, 23) = 6
last (line 4, 8, 9, 11, 23) = 5
sArray (line 2, 12, 17) = 3
tArray (line 2, 12, 17) = 3
sMax (line 2, 6) = 2
tMax (line 2, 8) = 2

Is there anything vital I've missed out? From my understanding:

  1. Operands are values
  2. Operators manipulate and check operands
2

There are 2 answers

1
dragn On BEST ANSWER

The point of Halstead's metrics is to answer a lot of questions like "How difficult is the code to read", "How much effort was put into writing the code", etc. The formula for Halstead's Difficulty metric should provide a hint on how the first question answered:

Difficulty = (Unique Operators / 2) * (Operands / Unique Operands);

You can see that having more unique operators, obviously, makes the code harder to read.

On braces: A lot of sources on the subject consider {} to be operators, which I don't see the point of. Curly braces act as a structure (punctuation) element and in a lot of ways makes code easier to understand, not harder. (Take, for example, conditional block with and without braces)

Counting the function name matched is relevant only in a more general context, but not when you measure the metrics of the function implementation (given there is no recursion).

On operators: counting operators can be tricky. For example, [] appearing in function declaration and [] on lines 12 and 17, are actually different things. The first one is array declaration, the second is operator[] - accessing element by index. The same with postfix and prefix ++, having them both in the program makes it harder to read.

The same logic applies to language keywords: for, if, else, break, return. The more of them in the code the harder it is to read.

On types: type names in variable declaration is also tricky. Some attribute them to operators, some to operands. But if we look again at the Difficulty formula, we would see that type names would better go to operators, in the sense that having more different types in the code make it harder to read, not easier.

Your counts for operands seems to be alright.

Operators 
= Assignment (line 6, 8, 9, 11, 19, 23) = 6 
< Less Than (line 6, 17) = 2 
++ Prefix Increment (line 6) = 1
++ Postfix Increment (line 14) = 1 
- Subtract (line 8, 23) = 2 
<= Less Than or Equal to (line 9) = 1 
+ Addition (line 11, 19) = 2 
/ Division (line 11) = 1 
== Equal to (line 12) = 1
[] declaration (line 2) = 2 
[] index (line 12, 17) = 4
for (line 6, 9) = 2
if (line 12, 17) = 2
else (line 21) = 1
break (line 15) = 1
return (line 27) = 1
int declaration = 7

Operands 
count (line 4, 14) = 2 
i (line 4, 6*3, 12, 17) = 6 
first (line 4, 9*2, 11, 19) = 5 
middle (line 4, 11, 12, 17, 19, 23) = 6 
last (line 4, 8, 9, 11, 23) = 5 
sArray (line 2, 12, 17) = 3 
tArray (line 2, 12, 17) = 3 
sMax (line 2, 6) = 2 
tMax (line 2, 8) = 2

Metrics
n1 = 17
n2 = 9
N1 = 37
N2 = 34
Difficulty = (n1 * N2) / (2 * n2) = 32.1

I was referring to Wiki and this page on Virtual Machinery.

By the way, most things said are my opinion, and may not coincide with more official sources.

By the way: 2, here is exact and strict definition on what should be counted as operators and operands in a C++ code: http://www.verifysoft.com/en_halstead_metrics.html.

7
Madhu Kumar Dadi On

firstly, initialize count to 0 and next operators are not values they are variables.

operators 
matched -1
() -6
[] -6
{} -6
int -7
for -2
if -2
else -1
return -1
= -6 
< -2
<= -1
++ -2
- -2
+ -2
/ -1
== -1
break -1

operands
2 -line no. 11 -1
1 (8,19,23) -3
0 -1
count -3
i -6
first -5
middle -6
last -5
sArray -3
tArray -3
sMax -2
tMax -2

N1=50
N2=40
n1=18
n2=12

The book I am referring to is Software Metrics and Software Metrology By Alain Abran. You can download it from here -> http://profs.etsmtl.ca/aabran/English/Accueil/ChapersBook/Abran%20-%20Chapter%20005.pdf

I hope it will solve all your doubts.

And function names,braces,type names,all other key words and all other well known operators come under operator section

Variables and constant values that are input to any functions or operators are operands.

Hence, I come up with this answer.