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

s would be an obvious way to constrain yourself to such values, though using `int`

s 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