Back

Should you normalize RGB values by 255 or by 256?
SiTech AI Team3 min read

Should you normalize RGB values by 255 or by 256?

Graphics programmer Pekka Väänänen examines the two common ways of converting 8-bit RGB values to floats and back, explaining when dividing by 255 is the right choice and when division by 256 can be justified.

Converting 8-bit colour values to floating point and back is one of the first decisions in any image-processing program, and there are two schools of thought. Graphics programmer Pekka Väänänen has published an analysis of the question on his blog 30fps.net, comparing the standard division by 255 with the alternative that adds a 0.5 bias and divides by 256.

The two formulas

The standard approach converts pixels with img / 255.0 and writes them back with trunc(result * 255 + 0.5), mapping the integer 0 to 0.0 and 255 to 1.0 — the same convention GPUs use for unsigned-normalised formats. The alternative converts with (img + 0.5) / 256.0 and writes with trunc(result * 256), which places every floating-point value exactly halfway between two integers.

The practical cost of the alternative is that black is no longer 0.0: the integer 0 decodes to 0.001953125, so code that wants to detect black must know that constant and is tied to the 8-bit input range. The author notes that images round-trip losslessly through the standard formula and that its inexactness — 128/255 is about 0.501961 — stays in the least significant bit, a relative error of roughly 0.00001 percent.

Half-sized bins at the extremes

The standard formula's weakness is at the edges. Because its floating-point range is slightly wider than [0, 1], the bins that round to 0 and to 255 are half the width of the others, so uniformly distributed noise produces the extreme values only half as often. The post shows this with a histogram of a million random values, then argues it rarely matters: values just outside the range still round to the correct integer, and a processing step that subtracts 0.005 from black ends at 0 in both schemes.

In the language of quantisation theory, the two options are a mid-riser quantiser with 255 levels and a mid-tread quantiser with 256. Reconstruction error is marginally lower for division by 256 — mean absolute error of 1/1024 against 1/1020 — but only when the same code controls both encoding and decoding. Loading other people's images with the alternative scale factor is, in theory, the wrong decode, and it mixes the two quantisers.

What to do

The conclusion is deliberately practical: if you are processing images you did not create, normalise by 255. Division by 256 is defensible when you control both saving and loading, do not need zero to map to zero and accept tying the processing code to an 8-bit range. The post also discusses a later "best method" proposed by Chris Lomont, which decodes with k/255.0 and encodes with clamp(floor(x * 256), 0, 255), keeping full-range floats and uniformly sized bins at the cost of roughly twice the quantisation error, peaking at the extremes.

SiTech

SiTech — AI-powered web development

We build fast, modern websites and bring AI into real business workflows. Have a project or a question? We'd love to help.