About map and error checking and preventing

map was once a simple function 4 times faster that looked like this:

static public float map(float value, float istart, float istop, float ostart, float ostop) {
    return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
}

basicly it returns out_min + norm(val, in_min, in_max) * out_range.

Then to avoid infinity and NaN problems a bunch off error checking was added.

Today I needed to be able to map from -Double.MAX_VALUE to Double.MAX_VALUE, you can see them like MIN_FLOAT and MAX_FLOAT but for double.

This is not possible with processing function. To begin, the range is needed. If you do this with MAX_FLOAT - MIN_FLOAT you get infinity for example.

I think the majority of the problems with NaN is bad input on the user site.
But for the range thing, I’m using the code at the bottom of the post now.
Also I wonder if it makes sense that processing get’s updated to have double as a fallback.

float map2(float value, float istart, float istop, float ostart, float ostop) {
  if (Float.isInfinite(istop - istart) || Float.isInfinite(ostop - ostart)) {
    return (float) mapDouble(value, istart, istop, ostart, ostop);
  }
  return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
}


double mapDouble(double value, double istart, double istop, double ostart, double ostop) {
  if (Double.isInfinite(istop - istart) || Double.isInfinite(ostop - ostart)) {
    value /= 2;
    istart /= 2;
    istop /= 2;
    ostart /= 2;
    ostop /= 2;
    return (ostart + (ostop - ostart) * ((value - istart) / (istop - istart))) * 2;
  }
  return ostart + (ostop - ostart) * ((value - istart) / (istop - istart));
}

Really interesting, thanks for sharing this.

Do you mean for there to be another signature for map?:

double map (double, double, double, double, double)

Just as a guess, that probably won’t happen because (I think) for consistency that would require supporting double signatures everywhere. lerp() doubles, PVector doubles, etc. And the Processing API is floats all the way down.

Or do you just mean an internal double map that isn’t part of the public API? Might be worth opening an issue about if you have a clear test case to demonstrate why it is helpful / needed.

I mean the latter, where the double one is not exposed but used to deal with cases where the range is exceeding the range of MAX_FLOAT (and therefor being infinity when it comes to floats).

Nice. Does the private fallback happen in the two min/max max/min special cases only, or across a range of values?