Given two ranges:

   



[

a

1


,

a

2


]


{\displaystyle [a_{1},a_{2}]}

   and 
   



[

b

1


,

b

2


]


{\displaystyle [b_{1},b_{2}]}

; 
   then a value   



s


{\displaystyle s}

   in range   



[

a

1


,

a

2


]


{\displaystyle [a_{1},a_{2}]}


   is linearly mapped to a value   



t


{\displaystyle t}

   in range   



[

b

1


,

b

2


]


{\displaystyle [b_{1},b_{2}]}


   where:



   



t
=

b

1


+



(
s
−

a

1


)
(

b

2


−

b

1


)


(

a

2


−

a

1


)





{\displaystyle t=b_{1}+{(s-a_{1})(b_{2}-b_{1}) \over (a_{2}-a_{1})}}




Task

Write a function/subroutine/... that takes two ranges and a real number, and returns the mapping of the real number from the first to the second range.

Use this function to map values from the range    [0, 10]    to the range    [-1, 0]. 



Extra credit

Show additional idiomatic ways of performing the mapping, using tools available to the language.




 
record Range(a, b)
 
# note, we force 'n' to be real, which means recalculation will 
# be using real numbers, not integers
procedure remap (range1, range2, n : real)
  if n < range2.a | n > range2.b then fail # n out of given range
  return range1.a + (n - range2.a) * (range1.b - range1.a) / (range2.b - range2.a)
end
 
procedure range_string (range)
  return "[" || range.a || ", " || range.b || "]"
end
 
procedure main ()
  range1 := Range (0, 10)
  range2 := Range (-1, 0)
  # if i is out of range1, then 'remap' fails, so only valid changes are written
  every i := -2 to 12 do {
    if m := remap (range2, range1, i)
      then write ("Value " || i || " in " || range_string (range1) || 
                  " maps to " || m || " in " || range_string (range2))
  }
end
 