Integers or Unsigned Integers

What is the recommended practice for computations involving only non-negative integers?

If one uses uint(w) to index an array declared as

var X : [1..1024] int(w); // probably should be 1..1024:uint(T.B.A.)

the compiler legitimately tells you that there in an indexing error.

Also, if one right shifts a signed int(w), even if it is only used for non-negative numbers, then a future Chapel static analyser (which does not yet exist) will complain about potential issues with the carry of the sign bit.

Hi Damian —

What is the recommended practice for computations involving only non-negative integers?

Using uints would be an obvious way to constrain yourself to such values, though using ints may be a more convenient alternative due to their prevalence in the language if you don't need that 64th bit worth of values.

If you go the uint path, you're correct that if you want to use uint(w)s to index into an array, you'll need to change the array's index type (idxType) to be uint(w). This can be done in a few different ways, one of which is by casting the bounds to uint(w)'s as you suggest, where—if they're params—I'd cast both bounds to be safe (unless you're very confident in internalizing what type Chapel unifies on for operators like + or .. — I'm not). So:

var X: [1:uint(w)..1024:uint(w)] int(w);

Stylistically, I prefer to write this as:

const ub = 1024: uint(w);
var X: [1..ub] int(w);

where, by switching the 1024 from a param to a const, I get out of the param-param coercion rules and into the simpler rules involving constants.

Also, if one right shifts a signed int (w), even if it is only used for non-negative numbers, then a future Chapel static analyser (which does not yet exist) will complain about potential issues with the carry of the sign bit.

Are you imagining that such a static analyzer will know whether or not the integer is positive or negative, or that it'll always warn when applying right-shift to an int(w)?

-Brad

The compiler will generally never know whether an int(w) is positive or negative.

But as you note, for convenience we often use an int(w) for numbers which should never be negative.

I just think it is useful to have an error message for any right shift on a signed integer because the instruction the compiler generates will always have a sign carry and that instruction has been proven in the past to be the source of errors. And I bet if you asked most programmers what >> did they would only ever say right shift and never qualify that by anything if applied to a signed integer. I sadly forget that myself sometimes.

Sorry for taking so long to reply. I thought I had.

1 Like

Hi Damian —

I hear you and would encourage you to propose that as a feature in a github issue.

-Brad

1 Like