Code patternsArithmeticSaturating subtract

Saturating subtract

Subtracts, but stops at zero instead of wrapping round.

Watch it run

The form “Two cells” works on 4 cells, named “x”, “y”, “flag” and “zero”. Press Play, drag the step slider forwards and back, or change x and y with the sliders:

The figure needs JavaScript. The program below is the result for the example values.

A plain subtraction cannot stop at zero, because nothing in a flat loop looks at the cell. So we take single steps and look each time.

Each round takes 1 from the amount to subtract. Then an if and else: if the value still has something, take 1 from it; if it is empty already, clear what is left of the amount.

The cost is one round per unit actually subtracted. That is the price of every "do not go below zero" by counting.

The code

This is the program the figure ran. It is brainfuck as it stands: copy it, or open it in the playground, where you can change it:

[->>+<[->-]>[<<[-]>>->]<<<]
Open in the playground27 characters

What it needs

Common mistakes
  • Looping on the value instead of on the amount: then the loop ends too early when the value is smaller.
  • Using this on large numbers. With wrapping cells of a known width, the clamp by bits (see shift, round and clamp) costs the same for every number.

What it costs

A plain step is one command. An optimised step is one step of an interpreter that folds runs of the same command and flat loops. Choose the values and watch the two bars; What costs what explains how cost is counted:

The figure needs JavaScript. The table below has the measured steps.

Cost as a formula, and measured
Table 1. The cost as a function of the values.
FormPlain stepsOptimised steps
Two cellsabout 16 per unit taken offabout 8 per unit taken off
By a constantabout 17 per unit of the amountabout 8 per unit of the amount
The project formgrows with n × valueabout 8 per unit of n
Table 2. Measured when this page was written.
FormValuesBitsCharactersPlain stepsOptimised steps
Two cellsx = 5; y = 38277133
Two cellsx = 3; y = 58274925
Two cellsx = 100; y = 2508271,601801
By a constantamount n = 4; value = 38317334
The project formamount n = 4; value = 384519731

Other forms

By a constant

The amount is written into the program, in cell 0. The value is in cell 1.

++++[->>+<[->-]>[<<[-]>>->]<<<]
Open in the playground31 characters
Run this form step by step

The form “By a constant” works on 4 cells, named “amount”, “value”, “flag” and “zero”. Press Play, drag the step slider forwards and back, or change amount n and value with the sliders:

The figure needs JavaScript. The program below is the result for the example values.

The project form

Tests a copy of the value each round, so the cells may lie anywhere. Layout: value, counter, two scratch cells.

>++++[-<[->>+>+<<<]>>>[-<<<+>>>]<[<<->>[-]]<]
Open in the playground45 characters
Run this form step by step

The form “The project form” works on 4 cells; the named ones are “value”, “counter” and “scratch”. Press Play, drag the step slider forwards and back, or change amount n and value with the sliders:

The figure needs JavaScript. The program below is the result for the example values.

Where it is used

Sources

Every program on this page was run on many inputs, in plain and in optimised mode, and compared with JavaScript. The explanations are written for this page.