Zig: Saturating arithmetic

Created on 24 Jul 2018  路  7Comments  路  Source: ziglang/zig

This proposal is more for the sake of completeness rather than something that should be added to Zig any time soon.

Zig has explicit support for integer operations with fault on overflow, and wrap-around behaviour. But there is a third relatively common behaviour for integer operations, especially in DSPs: saturating arithmetic: https://en.wikipedia.org/wiki/Saturation_arithmetic

Here's some related proposals from LLVM:
https://reviews.llvm.org/D6976
https://reviews.llvm.org/D8371

There are some options how to add support for this:

  1. Add more operators that perform saturating arithmetic on standard integer types
  2. Define a saturating integer type that uses saturating arithmetic when using the standard operators.
  3. Just have functions/built-ins for it

I don't have any opinion on how to implement it. This is just a basis for discussion, and I think Zig needs the input from someone with good experience with DSPs to get feedback on that use-case before this proposal is considered.

accepted proposal

Most helpful comment

Seems there are instructions in several architectures with saturating behavior, including ARM and SIMD. Makes sense to me that we should explicitly declare that behavior if we want it, rather than rely on the compiler to guess intent. Maybe it isn't enough of a common case to expend operators on and we should just use builtins (@saturateAdd(), etc), but it would be more consistent. To that end, I propose <op>|, for the simple reason that it looks like a wall.

a +| b;
a +|= b;

a -| b;
a -|= b;

a *| b;
a *|= b;

All 7 comments

where is such behaviour used/ wanted?

Seems there are instructions in several architectures with saturating behavior, including ARM and SIMD. Makes sense to me that we should explicitly declare that behavior if we want it, rather than rely on the compiler to guess intent. Maybe it isn't enough of a common case to expend operators on and we should just use builtins (@saturateAdd(), etc), but it would be more consistent. To that end, I propose <op>|, for the simple reason that it looks like a wall.

a +| b;
a +|= b;

a -| b;
a -|= b;

a *| b;
a *|= b;

@monouser7dig Basically any kind of signal processing math code. I guess what most people may be familiar is image processing. Imagine you want to double the brightness, so you multiply each value by 2. But you don't want the brightness to wrap around, so when it goes above 255, you clamp it to 255. The Wikipedia article explained it fairly well.

@tgschultz Yeah, that seems to be the most visually descriptive. But it could be confusing that | is used with bitwise or as well.

That鈥檚 a nice example, I think builtins for these operations would be a good addition.

Wouldn't @clampedAdd make more intuitive sense, considering that you'd implement this functionality with a call to some clamp function?

It's not like we want people to have to read Wikipedia articles to understand language features, right?

Note that LLVM has built-in support for saturating add and subtract: https://llvm.org/docs/LangRef.html#saturation-arithmetic-intrinsics

I've found them useful on a number of occasions in my Rust code, where saturating_add and saturating_sub methods are defined on all supported integer types. And having them built-in to the language means LLVM can properly reason-about and optimize the code.

I don't know if the status quo names are final, but the current naming convention is something like @opnameWithUniqueBehaviour, so perhaps:

@addWithClamping(a, b)
@subWithClamping(a, b)
@mulWithClamping(a, b)
@shlWithClamping(a, b)

However, afaik we don't have a @clamp operation, so this feels a little out of place. @clamp operation would also take a min and max parameter, which this would not, so perhaps a separate word is in order, even if it does require checking documentation.

@addWithSaturation(a, b)
@subWithSaturation(a, b)
@mulWithSaturation(a, b)
@shlWithSaturation(a, b)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

andersfr picture andersfr  路  3Comments

andrewrk picture andrewrk  路  3Comments

bheads picture bheads  路  3Comments

bronze1man picture bronze1man  路  3Comments

DavidYKay picture DavidYKay  路  3Comments