Skip to content

Instantly share code, notes, and snippets.

@fpillet
Created May 26, 2011 12:07
Show Gist options
  • Save fpillet/993002 to your computer and use it in GitHub Desktop.
Save fpillet/993002 to your computer and use it in GitHub Desktop.
Javascript value scaling between two ranges
/* Scale a value from one range to another
* Example of use:
*
* // Convert 33 from a 0-100 range to a 0-65535 range
* var n = scaleValue(33, [0,100], [0,65535]);
*
* // Ranges don't have to be positive
* var n = scaleValue(0, [-50,+50], [0,65535]);
*
* Ranges are defined as arrays of two values, inclusive
*
* The ~~ trick on return value does the equivalent of Math.floor, just faster.
*
*/
function scaleValue(value, from, to) {
var scale = (to[1] - to[0]) / (from[1] - from[0]);
var capped = Math.min(from[1], Math.max(from[0], value)) - from[0];
return ~~(capped * scale + to[0]);
}
@luccasmaso
Copy link

Nice, thanks

@illtellyoulater
Copy link

illtellyoulater commented Jan 25, 2023

The fact it only works with integers makes it a lot less precise with small numbers, for example:

scaleValue(26, [0, 100], [-2, 2]);
= 0

@illtellyoulater
Copy link

illtellyoulater commented Jan 25, 2023

The following solution (from Oleq's answer at https://stackoverflow.com/a/14224813/988591) works so much better:

function convertRange( value, r1, r2 ) { 
    return ( value - r1[ 0 ] ) * ( r2[ 1 ] - r2[ 0 ] ) / ( r1[ 1 ] - r1[ 0 ] ) + r2[ 0 ];
}

// example
convertRange(26, [0, 100], [-2, 2]);
= -0.96

// another example
convertRange(26, [0, 100.1], [-2, 2]);
= -0.9610389610389609

This is linear interpolation, which is essential in so many situations, but for some reason I keep forgetting and rediscovering it every 5 years or so... Hopefully this time it will stick... ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment