<!-- canonical: efficientnewlanguage.org/ai/examples/888-the-gradient-was-averaged-in-srgb | ai_layer_version: 0.1.0 | updated: 2026-09-17 -->

# Example 888 — The gradient was averaged in srgb

`the_gradient_was_averaged_in_srgb.eml` - A renderer draws a gradient from black to white by averaging the two endpoint pixel values for the middle, and the averaging is exact over every pixel. What the stored pixel values are an encoding of is computed below.

## EML

```eml
# Self-authored for the EML case corpus (no external origin). A renderer draws a
# gradient from black to white by averaging the two endpoint pixel values for
# the middle, and the averaging is exact over every pixel. What the stored pixel
# values are an encoding of is computed below.
#
# The render is careful. It reads the real endpoint pixel values, not constants
# typed in; it uses the engine's own integer average over every pixel; it
# produces a strictly monotone ramp; and the intent is exactly 'the middle of the
# gradient is half as bright as the end'.
#
# Pixel values are sRGB-encoded, a nonlinear encoding near a gamma of 2.2, so the
# encoded midpoint 127 decodes to about a fifth of full light, not half.

0 => black_srgb
255 => white_srgb
2120 => light_of_srgb_127_per_myriad
5000 => light_of_a_true_midpoint_per_myriad
188 => srgb_that_encodes_half_light

black_srgb + white_srgb => endpoint_sum
int(endpoint_sum / 2) => midpoint_by_averaging_encoded_values
light_of_a_true_midpoint_per_myriad - light_of_srgb_127_per_myriad => light_the_midpoint_lacks_per_myriad
int(light_of_srgb_127_per_myriad * 10000 / light_of_a_true_midpoint_per_myriad) => midpoint_share_of_intended_light_per_myriad

"black, sRGB                     : " + str(black_srgb) ^0
"white, sRGB                     : " + str(white_srgb) ^0
"midpoint by averaging the codes : " + str(midpoint_by_averaging_encoded_values) ^0
"" ^0
"light that sRGB 127 decodes to  : " + str(light_of_srgb_127_per_myriad) + " per ten thousand of full" ^0
"light a true midpoint has       : " + str(light_of_a_true_midpoint_per_myriad) + " per ten thousand of full" ^0
"sRGB code for half light        : " + str(srgb_that_encodes_half_light) ^0
"light the midpoint lacks        : " + str(light_the_midpoint_lacks_per_myriad) + " per ten thousand" ^0
"midpoint has, of intended light : " + str(midpoint_share_of_intended_light_per_myriad) + " per ten thousand" ^0
"" ^0

# ---- what the render verified ----

"the gradient render" ^0
"  reads : the real endpoint pixel values" ^0
"  average : the engine's own integer mean, every pixel" ^0
"  ramp : strictly monotone from 0 to 255" ^0
"  intent : the middle is half as bright as the end" ^0
"  pixels miscomputed : 0" ^0
"  verdict : MIDPOINT IS 127, EXACTLY HALFWAY BETWEEN THE CODES" ^0
"" ^0
"  averaging the real codes exactly over every pixel is the" ^0
"  part done right here, and it is why 127 is precisely the" ^0
"  middle of the code range" ^0
"" ^0

# ---- what the codes encode ----

"the sRGB encoding" ^0
"  what a pixel value is : a code, roughly light to the" ^0
"    power of one over 2.2" ^0
"  so halfway between the codes : is not halfway in light" ^0
"  code 127 decodes to : " + str(light_of_srgb_127_per_myriad) + " per ten thousand of full light" ^0
"  half light encodes to : code " + str(srgb_that_encodes_half_light) ^0
"  so the rendered middle : is dark, carrying " + str(midpoint_share_of_intended_light_per_myriad) + " per" ^0
"    ten thousand of the light it was meant to" ^0
"" ^0

# ---- what the viewer sees ----

"the gradient on screen" ^0
"  intended : a ramp whose middle is half as bright" ^0
"  rendered : a ramp whose middle is about a fifth as bright" ^0
"  is the average wrong : no; 127 is the mean of 0 and 255" ^0
"  is a mean of codes a mean of light : no; the encoding is" ^0
"    nonlinear and the mean was taken on the wrong side of it" ^0
"" ^0

# ---- null control ----

# The same gradient, averaged in linear light (decode, average, re-encode).
127 => nc_midpoint_averaged_as_codes
188 => nc_midpoint_averaged_in_linear_light
5000 => nc_light_of_the_linear_midpoint_per_myriad

"null control - average in linear light, then re-encode" ^0
"  midpoint, averaging codes : " + str(nc_midpoint_averaged_as_codes) ^0
"  midpoint, averaging light : " + str(nc_midpoint_averaged_in_linear_light) ^0
"  light of that midpoint : " + str(nc_light_of_the_linear_midpoint_per_myriad) + " per ten thousand" ^0
"  no endpoint and no pixel count changed; the mean stopped" ^0
"  being taken over the encoding" ^0
"" ^0

# ---- the rule ----

"what an average of two pixel codes guarantees" ^0
"  the result is halfway between the codes : exactly, the" ^0
"    engine's own mean over every pixel" ^0
"  the result is halfway in brightness : not addressed; the" ^0
"    codes are sRGB, a nonlinear encoding, so code " + str(midpoint_by_averaging_encoded_values) + " is" ^0
"    " + str(light_of_srgb_127_per_myriad) + " per ten thousand of full light where half light is code " + str(srgb_that_encodes_half_light) ^0
"" ^0

"an encoding is a curve, and the middle of a curve's inputs is not the middle" ^0
"of its outputs; arithmetic done on the codes is arithmetic on the wrong side of" ^0
"the curve, exact about numbers that are not the quantity" ^0
"" ^0

"It averages the real codes exactly over every pixel - 127 is the middle of the" ^0
"code range. But the codes are sRGB, so 127 decodes to " + str(light_of_srgb_127_per_myriad) + " per ten thousand of" ^0
"full light where half light is code " + str(srgb_that_encodes_half_light) + "; the middle of the gradient carries " + str(midpoint_share_of_intended_light_per_myriad) ^0
"per ten thousand of the light it was meant to, until the mean is taken in linear light." ^0
```

## Python (deterministic transpilation)

```python
black_srgb = 0
white_srgb = 255
light_of_srgb_127_per_myriad = 2120
light_of_a_true_midpoint_per_myriad = 5000
srgb_that_encodes_half_light = 188
endpoint_sum = black_srgb + white_srgb
midpoint_by_averaging_encoded_values = int(endpoint_sum / 2)
light_the_midpoint_lacks_per_myriad = light_of_a_true_midpoint_per_myriad - light_of_srgb_127_per_myriad
midpoint_share_of_intended_light_per_myriad = int(light_of_srgb_127_per_myriad * 10000 / light_of_a_true_midpoint_per_myriad)
print("black, sRGB                     : " + str(black_srgb))
print("white, sRGB                     : " + str(white_srgb))
print("midpoint by averaging the codes : " + str(midpoint_by_averaging_encoded_values))
print("")
print("light that sRGB 127 decodes to  : " + str(light_of_srgb_127_per_myriad) + " per ten thousand of full")
print("light a true midpoint has       : " + str(light_of_a_true_midpoint_per_myriad) + " per ten thousand of full")
print("sRGB code for half light        : " + str(srgb_that_encodes_half_light))
print("light the midpoint lacks        : " + str(light_the_midpoint_lacks_per_myriad) + " per ten thousand")
print("midpoint has, of intended light : " + str(midpoint_share_of_intended_light_per_myriad) + " per ten thousand")
print("")
print("the gradient render")
print("  reads : the real endpoint pixel values")
print("  average : the engine's own integer mean, every pixel")
print("  ramp : strictly monotone from 0 to 255")
print("  intent : the middle is half as bright as the end")
print("  pixels miscomputed : 0")
print("  verdict : MIDPOINT IS 127, EXACTLY HALFWAY BETWEEN THE CODES")
print("")
print("  averaging the real codes exactly over every pixel is the")
print("  part done right here, and it is why 127 is precisely the")
print("  middle of the code range")
print("")
print("the sRGB encoding")
print("  what a pixel value is : a code, roughly light to the")
print("    power of one over 2.2")
print("  so halfway between the codes : is not halfway in light")
print("  code 127 decodes to : " + str(light_of_srgb_127_per_myriad) + " per ten thousand of full light")
print("  half light encodes to : code " + str(srgb_that_encodes_half_light))
print("  so the rendered middle : is dark, carrying " + str(midpoint_share_of_intended_light_per_myriad) + " per")
print("    ten thousand of the light it was meant to")
print("")
print("the gradient on screen")
print("  intended : a ramp whose middle is half as bright")
print("  rendered : a ramp whose middle is about a fifth as bright")
print("  is the average wrong : no; 127 is the mean of 0 and 255")
print("  is a mean of codes a mean of light : no; the encoding is")
print("    nonlinear and the mean was taken on the wrong side of it")
print("")
nc_midpoint_averaged_as_codes = 127
nc_midpoint_averaged_in_linear_light = 188
nc_light_of_the_linear_midpoint_per_myriad = 5000
print("null control - average in linear light, then re-encode")
print("  midpoint, averaging codes : " + str(nc_midpoint_averaged_as_codes))
print("  midpoint, averaging light : " + str(nc_midpoint_averaged_in_linear_light))
print("  light of that midpoint : " + str(nc_light_of_the_linear_midpoint_per_myriad) + " per ten thousand")
print("  no endpoint and no pixel count changed; the mean stopped")
print("  being taken over the encoding")
print("")
print("what an average of two pixel codes guarantees")
print("  the result is halfway between the codes : exactly, the")
print("    engine's own mean over every pixel")
print("  the result is halfway in brightness : not addressed; the")
print("    codes are sRGB, a nonlinear encoding, so code " + str(midpoint_by_averaging_encoded_values) + " is")
print("    " + str(light_of_srgb_127_per_myriad) + " per ten thousand of full light where half light is code " + str(srgb_that_encodes_half_light))
print("")
print("an encoding is a curve, and the middle of a curve's inputs is not the middle")
print("of its outputs; arithmetic done on the codes is arithmetic on the wrong side of")
print("the curve, exact about numbers that are not the quantity")
print("")
print("It averages the real codes exactly over every pixel - 127 is the middle of the")
print("code range. But the codes are sRGB, so 127 decodes to " + str(light_of_srgb_127_per_myriad) + " per ten thousand of")
print("full light where half light is code " + str(srgb_that_encodes_half_light) + "; the middle of the gradient carries " + str(midpoint_share_of_intended_light_per_myriad))
print("per ten thousand of the light it was meant to, until the mean is taken in linear light.")
```

## stdout (executed)

```text
black, sRGB                     : 0
white, sRGB                     : 255
midpoint by averaging the codes : 127

light that sRGB 127 decodes to  : 2120 per ten thousand of full
light a true midpoint has       : 5000 per ten thousand of full
sRGB code for half light        : 188
light the midpoint lacks        : 2880 per ten thousand
midpoint has, of intended light : 4240 per ten thousand

the gradient render
  reads : the real endpoint pixel values
  average : the engine's own integer mean, every pixel
  ramp : strictly monotone from 0 to 255
  intent : the middle is half as bright as the end
  pixels miscomputed : 0
  verdict : MIDPOINT IS 127, EXACTLY HALFWAY BETWEEN THE CODES

  averaging the real codes exactly over every pixel is the
  part done right here, and it is why 127 is precisely the
  middle of the code range

the sRGB encoding
  what a pixel value is : a code, roughly light to the
    power of one over 2.2
  so halfway between the codes : is not halfway in light
  code 127 decodes to : 2120 per ten thousand of full light
  half light encodes to : code 188
  so the rendered middle : is dark, carrying 4240 per
    ten thousand of the light it was meant to

the gradient on screen
  intended : a ramp whose middle is half as bright
  rendered : a ramp whose middle is about a fifth as bright
  is the average wrong : no; 127 is the mean of 0 and 255
  is a mean of codes a mean of light : no; the encoding is
    nonlinear and the mean was taken on the wrong side of it

null control - average in linear light, then re-encode
  midpoint, averaging codes : 127
  midpoint, averaging light : 188
  light of that midpoint : 5000 per ten thousand
  no endpoint and no pixel count changed; the mean stopped
  being taken over the encoding

what an average of two pixel codes guarantees
  the result is halfway between the codes : exactly, the
    engine's own mean over every pixel
  the result is halfway in brightness : not addressed; the
    codes are sRGB, a nonlinear encoding, so code 127 is
    2120 per ten thousand of full light where half light is code 188

an encoding is a curve, and the middle of a curve's inputs is not the middle
of its outputs; arithmetic done on the codes is arithmetic on the wrong side of
the curve, exact about numbers that are not the quantity

It averages the real codes exactly over every pixel - 127 is the middle of the
code range. But the codes are sRGB, so 127 decodes to 2120 per ten thousand of
full light where half light is code 188; the middle of the gradient carries 4240
per ten thousand of the light it was meant to, until the mean is taken in linear light.
```

## Round-trip

`ok: true` — round-trip fixpoint reached (python1 == python2)

## Trace event types

eml:run:start · eml:assign · eml:output · eml:run:done
