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.




INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
 
PROC Map(REAL POINTER a1,a2,b1,b2,s,res)
  REAL tmp1,tmp2,tmp3
 
  RealSub(s,a1,tmp1) ;tmp1=s-a1
  RealSub(b2,b1,tmp2) ;tmp2=b2-b1
  RealMult(tmp1,tmp2,tmp3) ;tmp3=(s-a1)*(b2-b1)
  RealSub(a2,a1,tmp1) ;tmp1=a2-a1
  RealDiv(tmp3,tmp1,tmp2) ;tmp2=(s-a1)*(b2-b1)/(a2-a1)
  RealAdd(b1,tmp2,res) ;res=b1+(s-a1)*(b2-b1)/(a2-a1)
RETURN
 
PROC Main()
  BYTE i
  REAL a1,a2,b1,b2,s,res
 
  Put(125) PutE() ;clear screen
 
  ValR("0",a1) ValR("10",a2)
  ValR("-1",b1) ValR("0",b2)
 
  FOR i=0 TO 10
  DO
    IntToReal(i,s)
    Map(a1,a2,b1,b2,s,res)
    PrintR(s) Print(" maps to ")
    PrintRE(res)
  OD
RETURN