#This work is licensed under the
#Creative Commons Attribution-Share Alike 3.0 United States License.
#To view a copy of this license, visit
#http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter to
#Creative Commons,
#171 Second Street, Suite 300,
#San Francisco, California, 94105, USA.

INPUT "a signed residual",entropies;
OUTPUT m[i],offset[i],add[i],sign[i],entropies;
VAR residual "residual";
VAR offset "offset";
VAR add "add";
VAR sign "sign";
VAR entropies "entropies";
VAR unsigned_ "unsigned";
VAR median "median";
if residual >= 0 {
    unsigned_ <- residual;
    sign[i] <- 0;
} else {
    unsigned_ <- -residual - 1;
    sign[i] <- 1;
}
median[0] <- floor(entropies[0] / 2 ^ 4) + 1;
median[1] <- floor(entropies[1] / 2 ^ 4) + 1;
median[2] <- floor(entropies[2] / 2 ^ 4) + 1;
if unsigned_ < median[0] {
    m[i] <- 0;
    offset[i] <- unsigned_;
    add[i] <- median[0] - 1;
    entropies[0] <- entropies[0] - floor((entropies[0] + 126) / 128) * 2;
} elif (unsigned_ - median[0]) < median[1] {
    m[i] <- 1;
    offset[i] <- unsigned_ - median[0];
    add[i] <- median[1] - 1;
    entropies[0] <- entropies[0] + floor((entropies[0] + 128) / 128) * 5;
    entropies[1] <- entropies[1] - floor((entropies[1] + 62) / 64) * 2;
} elif (unsigned_ - (median[0] + median[1])) < median[2] {
    m[i] <- 2;
    offset[i] <- unsigned_ - (median[0] + median[1]);
    add[i] <- median[2] - 1;
    entropies[0] <- entropies[0] + floor((entropies[0] + 128) / 128) * 5;
    entropies[1] <- entropies[1] + floor((entropies[1] + 64) / 64) * 5;
    entropies[2] <- entropies[2] - floor((entropies[2] + 30) / 32) * 2;
} else {
    m[i] <- floor((unsigned_ - (median[0] + median[1])) / median[2]) + 2;
    offset[i] <- unsigned_ - (median[0] + median[1] + ((m[i] - 2) * median[2]));
    add[i] <- median[2] - 1;
    entropies[0] <- entropies[0] + floor((entropies[0] + 128) / 128) * 5;
    entropies[1] <- entropies[1] + floor((entropies[1] + 64) / 64) * 5;
    entropies[2] <- entropies[2] + floor((entropies[2] + 32) / 32) * 5;
}
return m[i],offset[i],add[i],sign[i],entropies;