"normalizing" a value
Steven D'Aprano
steve at pearwood.info
Thu Jul 2 04:15:11 CEST 2015
On Thu, 2 Jul 2015 10:12 am, bvdp wrote:
> Not sure what this is called (and I'm sure it's not normalize). Perhaps
> "scaling"?
Could be normalising, could be scaling.
> Anyway, I need to convert various values ranging from around -50 to 50 to
> an 0 to 12 range (this is part of a MIDI music program). I have a number
> of places where I do:
You say "around" -50 to 50. Can you get 51? 151? How do you want to treat
such out of range numbers?
Are the values integer valued, or can they include fractional values like
27.356?
> while x < 0: x += 12
> while x >= 12: x -= 12
>
> Okay, that works. Just wondering if there is an easier (or faster) way to
> accomplish this.
One approach is to just re-scale the numbers from the range -50...50 to
0...12 inclusive. That is:
before => after
-50 => 0
0 => 6
50 => 12
and everything in between is scaled equivalently. Given x between -50 and 50
inclusive, calculate:
y = (x+50)/100.0*12
(Note that in Python 2, you need to make at least one of those values a
float, otherwise you may get unexpected results.)
That will give you y values from the range 0.0 to 12.0 inclusive. If x is
less than -50.0 or more than +50.0 y will likewise be out of range. You can
clip the result:
y = min(12.0, max(0.0, y))
If your x values are integer values (no fractional values) between -50 and
+50 you can use clock arithmetic. Think of a clock marked 0 to 12 (so there
are 13 values), once you reach 12 adding 1 takes you back to 0.
0, 13, 26, 39 => 0
1, 14, 27, 40 => 1
2, 15, 28, 41 => 2
...
12, 25, 38, 51 => 12
Extending that to negative values in the most obvious fashion:
-1, -14, -27, -40 => 12
...
-12, -25, -38, -51 => 1
-13, -26, -39, -52 => 0
We can do that easily with the % (modulo) operator:
y = x % y
Modulo even works with non-integer values:
py> 13.5 % 13
0.5
--
Steven
More information about the Python-list
mailing list