Map range: Difference between revisions

40,441 bytes added ,  1 month ago
Added Easylang
(→‎{{header|Ring}}: Output issue?)
(Added Easylang)
 
(86 intermediate revisions by 42 users not shown)
Line 21:
Show additional idiomatic ways of performing the mapping, using tools available to the language.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F maprange(a, b, s)
R b[0] + (Float(s - a[0]) * (b[1] - b[0]) / (a[1] - a[0]))
 
L(s) 0..10
print(‘#2 maps to #.’.format(s, maprange((0, 10), (-1, 0), s)))</syntaxhighlight>
 
{{out}}
<pre>
0 maps to -1
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0
</pre>
 
=={{header|6502 Assembly}}==
A range like [0, n] for some natural number <code>n < 255</code> can be easily mapped with a lookup table. The second range can be anything, as long as each entry is the same length and are stored consecutively in the desired order. This method requires a bit of compile-time knowledge, but is very efficient in terms of speed. Each element <code>Bn</code> is stored at relative offset <code>An</code> .
 
<syntaxhighlight lang="6502asm">mapping:
byte $00,$00,$80,$BF ;-1.0f (stored little-endian so the bytes are backwards)
byte $66,$66,$66,$BF ;-0.9f
byte $CD,$CC,$4C,$BF ;-0.8f
byte $33,$33,$33,$BF ;-0.7f
etc.</syntaxhighlight>
 
If the range isn't [0, n], but begins at some other natural number [k, n] where <tt>k,n < 255 </tt>, we can express it as [0, n-k] instead and simply subtract the "key" at runtime to get the offset.
 
This method is very convenient for implementing ASCII into hardware that lacks a built-in system font (like the NES). You can save graphics memory by mapping tile number 0 to ASCII 32, tile number 01 to 33, and so on. Had you mapped them "correctly," (i.e. tile number 32 to ASCII 32) you would still need a "blank tile" as tile number zero. So the easier solution is to subtract 32 from the character code before printing.
 
<syntaxhighlight lang="6502asm">;runs during non-maskable interrupt.
PrintChar:
;a = char to print
SEC
SBC #$32 ;subtract ascii offset to map the index to the correct tile graphics data.
 
;everything below this comment is hardware-specific mumbo-jumbo, feel free to ignore it if you don't care.
;ideally you'd want to do this before getting here so that the only thing that happens during NMI is the write to vram.
pha
LDA Cursor_Y
ASL
ASL
ASL
ASL
ASL
STA tempY ;row * 32
LDA #$20
ADC Cursor_X
STA tempX
LDA $2002 ;reset picture processor high-low latch
LDA tempX
STA $2006 ;this register is big-endian for some reason. Which is why I had to store Cursor_Y << 5 into tempY rather than here directly.
LDA tempY
STA $2006
PLA
STA $2007</syntaxhighlight>
 
=={{header|ACL2}}==
 
<langsyntaxhighlight Lisplang="lisp">(defun mapping (a1 a2 b1 b2 s)
(+ b1 (/ (* (- s a1)
(- b2 b1))
Line 39 ⟶ 104:
;; (-1 -9/10 -4/5 -7/10 -3/5 -1/2 -2/5 -3/10 -1/5 -1/10 0)
 
</syntaxhighlight>
</lang>
 
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
<syntaxhighlight lang="action!">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</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Map_range.png Screenshot from Atari 8-bit computer]
<pre>
0 maps to -1
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0
</pre>
 
=={{header|Ada}}==
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
procedure Map is
type First_Range is new Float range 0.0 .. 10.0;
Line 75 ⟶ 188:
Test_Value := Test_Value + 1.0;
end loop;
end Map;</langsyntaxhighlight>
 
{{out}}
Line 91 ⟶ 204:
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68"># maps a real s in the range [ a1, a2 ] to the range [ b1, b2 ] #
# there are no checks that s is in the range or that the ranges are valid #
PROC map range = ( REAL s, a1, a2, b1, b2 )REAL:
Line 99 ⟶ 212:
FOR i FROM 0 TO 10 DO
print( ( whole( i, -2 ), " maps to ", fixed( map range( i, 0, 10, -1, 0 ), -8, 2 ), newline ) )
OD</langsyntaxhighlight>
{{out}}
<pre>
Line 114 ⟶ 227:
10 maps to 0.00
</pre>
=={{header|Amazing Hopper}}==
La función "Seqspaced" es una macro-sustitución de "seqsp", y está construida, internamente, como una rutina en C que realiza el siguiente cálculo (en pseudocódigo):
<syntaxhighlight lang="c">
double inc = (nHasta - nDesde) / ( nTotal - 1);
lista[0] = nDesde;
lista[nTotal] = nHasta;
for( n=1; n<nTotal; n++){
lista[n] = lista[n-1] + inc;
}
</syntaxhighlight>
Macro-sustitución de "Seqspaced":
<syntaxhighlight lang="amazing hopper">
#defn Seqspaced(__X__,__Y__,__Z__,_V_) #ATOM#CMPLX;#ATOM#CMPLX;#ATOM#CMPLX;keep;lthan(1);\
do{{"Seqspaced: num elements < 1"}throw(2301)},seqsp(_V_)
</syntaxhighlight>
Otras macrosustituciones:
<syntaxhighlight lang="amazing hopper">
#defn Toksep(__X__) #ATOM#CMPLX;toksep;
#defn Cat(_X_,*) #ATOM#CMPLX;#GENCODE $$$*$$$ #ATCMLIST;cat; #ENDGEN
#defn Justleft(_X_,_V_) {" "};#ATOM#CMPLX;#ATOM#CMPLX;padright;
</syntaxhighlight>
Código que resuelve la tarea:
<syntaxhighlight lang="amazing hopper">
#include <jambo.h>
Main
v=0,w=0
Seqspaced(-1,0,11,w) // [-1,0}->[0-10]=11 números
Seqspaced(0,10,11,v)
Toksep( "\n" )
Cat( Justright(5,Str(v))," => ",Justright(5,Str(w))), Prnl
End
</syntaxhighlight>
{{out}}
<pre>
$ hopper maprange.jambo
0 => -1
1 => -0.9
2 => -0.8
3 => -0.7
4 => -0.6
5 => -0.5
6 => -0.4
7 => -0.3
8 => -0.2
9 => -0.1
10 => 0
$
</pre>
 
=={{header|AppleScript}}==
<syntaxhighlight lang="applescript">------------------------ MAP RANGE -----------------------
 
-- rangeMap :: (Num, Num) -> (Num, Num) -> Num -> Num
on rangeMap(a, b)
script
on |λ|(s)
set {a1, a2} to a
set {b1, b2} to b
b1 + ((s - a1) * (b2 - b1)) / (a2 - a1)
end |λ|
end script
end rangeMap
 
 
--------------------------- TEST -------------------------
on run
set mapping to rangeMap({0, 10}, {-1, 0})
set xs to enumFromTo(0, 10)
set ys to map(mapping, xs)
set zs to map(approxRatio(0), ys)
unlines(zipWith3(formatted, xs, ys, zs))
end run
 
 
------------------------- DISPLAY ------------------------
 
-- formatted :: Int -> Float -> Ratio -> String
on formatted(x, m, r)
set fract to showRatio(r)
set {n, d} to splitOn("/", fract)
(justifyRight(2, space, x as string) & " -> " & ¬
justifyRight(4, space, m as string)) & " = " & ¬
justifyRight(2, space, n) & "/" & d
end formatted
 
 
-------------------- GENERIC FUNCTIONS -------------------
 
-- Absolute value.
-- abs :: Num -> Num
on abs(x)
if 0 > x then
-x
else
x
end if
end abs
 
 
-- approxRatio :: Real -> Real -> Ratio
on approxRatio(epsilon)
script
on |λ|(n)
if {real, integer} contains (class of epsilon) and 0 < epsilon then
set e to epsilon
else
set e to 1 / 10000
end if
script gcde
on |λ|(e, x, y)
script _gcd
on |λ|(a, b)
if b < e then
a
else
|λ|(b, a mod b)
end if
end |λ|
end script
|λ|(abs(x), abs(y)) of _gcd
end |λ|
end script
set c to |λ|(e, 1, n) of gcde
ratio((n div c), (1 div c))
end |λ|
end script
end approxRatio
 
 
-- enumFromTo :: Int -> Int -> [Int]
on enumFromTo(m, n)
if m ≤ n then
set lst to {}
repeat with i from m to n
set end of lst to i
end repeat
return lst
else
return {}
end if
end enumFromTo
 
 
-- gcd :: Int -> Int -> Int
on gcd(a, b)
set x to abs(a)
set y to abs(b)
repeat until y = 0
if x > y then
set x to x - y
else
set y to y - x
end if
end repeat
return x
end gcd
 
 
-- justifyLeft :: Int -> Char -> String -> String
on justifyLeft(n, cFiller, strText)
if n > length of strText then
text 1 thru n of (strText & replicate(n, cFiller))
else
strText
end if
end justifyLeft
 
 
-- justifyRight :: Int -> Char -> String -> String
on justifyRight(n, cFiller, strText)
if n > length of strText then
text -n thru -1 of ((replicate(n, cFiller) as text) & strText)
else
strText
end if
end justifyRight
 
 
-- length :: [a] -> Int
on |length|(xs)
set c to class of xs
if list is c or string is c then
length of xs
else
(2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
end if
end |length|
 
 
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
 
 
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
 
 
-- minimum :: Ord a => [a] -> a
on minimum(xs)
set lng to length of xs
if lng < 1 then return missing value
set m to item 1 of xs
repeat with x in xs
set v to contents of x
if v < m then set m to v
end repeat
return m
end minimum
 
 
-- ratio :: Int -> Int -> Ratio Int
on ratio(x, y)
script go
on |λ|(x, y)
if 0 ≠ y then
if 0 ≠ x then
set d to gcd(x, y)
{type:"Ratio", n:(x div d), d:(y div d)}
else
{type:"Ratio", n:0, d:1}
end if
else
missing value
end if
end |λ|
end script
go's |λ|(x * (signum(y)), abs(y))
end ratio
 
 
-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary
-- assembly of a target length
-- replicate :: Int -> a -> [a]
on replicate(n, a)
set out to {}
if n < 1 then return out
set dbl to {a}
repeat while (n > 1)
if (n mod 2) > 0 then set out to out & dbl
set n to (n div 2)
set dbl to (dbl & dbl)
end repeat
return out & dbl
end replicate
 
 
-- showRatio :: Ratio -> String
on showRatio(r)
(n of r as string) & "/" & (d of r as string)
end showRatio
 
 
-- signum :: Num -> Num
on signum(x)
if x < 0 then
-1
else if x = 0 then
0
else
1
end if
end signum
 
 
-- splitOn :: String -> String -> [String]
on splitOn(pat, src)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, pat}
set xs to text items of src
set my text item delimiters to dlm
return xs
end splitOn
 
 
-- take :: Int -> [a] -> [a]
-- take :: Int -> String -> String
on take(n, xs)
set c to class of xs
if list is c then
if 0 < n then
items 1 thru min(n, length of xs) of xs
else
{}
end if
else if string is c then
if 0 < n then
text 1 thru min(n, length of xs) of xs
else
""
end if
else if script is c then
set ys to {}
repeat with i from 1 to n
set v to xs's |λ|()
if missing value is v then
return ys
else
set end of ys to v
end if
end repeat
return ys
else
missing value
end if
end take
 
 
-- unlines :: [String] -> String
on unlines(xs)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set str to xs as text
set my text item delimiters to dlm
str
end unlines
 
 
-- zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
on zipWith3(f, xs, ys, zs)
set lng to minimum({length of xs, length of ys, length of zs})
if 1 > lng then return {}
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, item i of ys, item i of zs)
end repeat
return lst
end tell
end zipWith3</syntaxhighlight>
{{Out}}
<pre> 0 -> -1.0 = -1/1
1 -> -0.9 = -9/10
2 -> -0.8 = -4/5
3 -> -0.7 = -7/10
4 -> -0.6 = -3/5
5 -> -0.5 = -1/2
6 -> -0.4 = -2/5
7 -> -0.3 = -3/10
8 -> -0.2 = -1/5
9 -> -0.1 = -1/10
10 -> 0.0 = 0/1</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">getMapped: function [a,b,i][
round .to:1 b\0 + ((i - a\0) * (b\1 - b\0))/(a\1 - a\0)
]
 
rangeA: @[0.0 10.0]
rangeB: @[0-1.0 0.0]
 
loop 0..10 'x [
mapped: getMapped rangeA rangeB to :floating x
print [x "maps to" mapped]
]</syntaxhighlight>
 
{{out}}
 
<pre>0 maps to -1.0
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0.0</pre>
 
=={{header|AutoHotkey}}==
{{trans|C}}
<syntaxhighlight lang="autohotkey">
<lang AutoHotkey>
mapRange(a1, a2, b1, b2, s)
{
Line 128 ⟶ 635:
out .= "f(" A_Index-1 ") = " mapRange(0,10,-1,0,A_Index-1) "`n"
MsgBox % out
</syntaxhighlight>
</lang>
 
=={{header|Axiom}}==
Axiom provides a Segment domain for intervals. The following uses a closure for a mapRange function over fields, which provides for some generality.
<lang Axiom>)abbrev package TESTP TestPackage
TestPackage(R:Field) : with
mapRange: (Segment(R), Segment(R)) -> (R->R)
== add
mapRange(fromRange, toRange) ==
(a1,a2,b1,b2) := (lo fromRange,hi fromRange,lo toRange,hi toRange)
(x:R):R +-> b1+(x-a1)*(b2-b1)/(a2-a1)</lang>
Use:<lang Axiom>f := mapRange(1..10,a..b)
[(xi,f xi) for xi in 1..10]</lang>
{{out}}
<pre> b + 8a 2b + 7a b + 2a 4b + 5a 5b + 4a
[(1,a), (2,------), (3,-------), (4,------), (5,-------), (6,-------),
9 9 3 9 9
2b + a 7b + 2a 8b + a
(7,------), (8,-------), (9,------), (10,b)]
3 9 9
Type: List(Tuple(Fraction(Polynomial(Integer))))</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f MAP_RANGE.AWK
BEGIN {
Line 166 ⟶ 653:
return b1 + ((num-a1) * (b2-b1) / (a2-a1))
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 181 ⟶ 668:
10 maps to 0
</pre>
 
=={{header|Axiom}}==
Axiom provides a Segment domain for intervals. The following uses a closure for a mapRange function over fields, which provides for some generality.
<syntaxhighlight lang="axiom">)abbrev package TESTP TestPackage
TestPackage(R:Field) : with
mapRange: (Segment(R), Segment(R)) -> (R->R)
== add
mapRange(fromRange, toRange) ==
(a1,a2,b1,b2) := (lo fromRange,hi fromRange,lo toRange,hi toRange)
(x:R):R +-> b1+(x-a1)*(b2-b1)/(a2-a1)</syntaxhighlight>
Use:<syntaxhighlight lang="axiom">f := mapRange(1..10,a..b)
[(xi,f xi) for xi in 1..10]</syntaxhighlight>
{{out}}
<pre> b + 8a 2b + 7a b + 2a 4b + 5a 5b + 4a
[(1,a), (2,------), (3,-------), (4,------), (5,-------), (6,-------),
9 9 3 9 9
2b + a 7b + 2a 8b + a
(7,------), (8,-------), (9,------), (10,b)]
3 9 9
Type: List(Tuple(Fraction(Polynomial(Integer))))</pre>
 
=={{header|BASIC}}==
==={{header|BASIC256}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">function MapRange(s, a1, a2, b1, b2)
return b1+(s-a1)*(b2-b1)/(a2-a1)
end function
 
for i = 0 to 10
print i; " maps to "; MapRange(i,0,10,-1,0)
next i
end</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
 
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> @% = 5 : REM Column width
DIM range{l, h}
DIM A{} = range{}, B{} = range{}
Line 197 ⟶ 718:
DEF FNmaprange(a{}, b{}, s)
= b.l + (s - a.l) * (b.h - b.l) / (a.h - a.l)</langsyntaxhighlight>
{{out}}
<pre>
Line 214 ⟶ 735:
 
==={{header|Commodore BASIC}}===
<langsyntaxhighlight lang="commodorebasic">10 REM MAP RANGE
20 REM COMMODORE BASIC 2.0
30 REM ================================
Line 222 ⟶ 743:
70 FOR S=0 TO 10
80 PRINT S;"MAPS TO ";FN MR(S)
90 NEXT</langsyntaxhighlight>
 
{{out}}
Line 238 ⟶ 759:
10 MAPS TO 0
</pre>
 
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 PROGRAM "MapRange.bas"
110 LET A1=0:LET A2=10
120 LET B1=-1:LET B2=0
130 DEF MR(S)=B1+(S-A1)*(B2-B1)/(A2-A1)
140 FOR I=0 TO 10
150 PRINT I;"maps to ";MR(I)
160 NEXT</syntaxhighlight>
 
=={{header|bc}}==
<langsyntaxhighlight lang="bc">/* map s from [a, b] to [c, d] */
define m(a, b, c, d, s) {
return (c + (s - a) * (d - c) / (b - a))
Line 255 ⟶ 785:
i; " => "; m(0, 10, -1, 0, i)
}
quit</langsyntaxhighlight>
 
{{out}}
Line 272 ⟶ 802:
=> 0.000000</pre>
 
=={{header|BQN}}==
A direct implementation of the specification.
 
<code>_map_</code> is a 2-modifier which returns a mapping function given two ranges.
 
<syntaxhighlight lang="bqn">_map_ ← {
a1‿a2 _𝕣_ b1‿b2 s:
b1 + ((s - a1) × b2 - b1) ÷ a2 - a1
}
 
ZeroTen ← 0‿10 _map_ ¯1‿0
 
•Show ZeroTen 0.1
•Show ZeroTen 8</syntaxhighlight>
<syntaxhighlight lang="bqn">¯0.99
¯0.19999999999999996</syntaxhighlight>
[https://mlochbaum.github.io/BQN/try.html#code=X21hcF8g4oaQIHsKIGEx4oC/YTIgX/CdlaNfIGIx4oC/YjIgczoKIGIxICsgKChzIC0gYTEpIMOXIGIyIC0gYjEpIMO3IGEyIC0gYTEKfQoKWmVyb1RlbiDihpAgMOKAvzEwIF9tYXBfIMKvMeKAvzAKCuKAolNob3cgWmVyb1RlbiAwLjEK4oCiU2hvdyBaZXJvVGVuIDEw Try It!]
=={{header|Bracmat}}==
{{trans|C}}
<langsyntaxhighlight lang="bracmat">( ( mapRange
= a1,a2,b1,b2,s
. !arg:(?a1,?a2.?b1,?b2.?s)
Line 286 ⟶ 833:
& 1+!n:?n
)
);</langsyntaxhighlight>
{{out}}
<pre>Mapping [0,10] to [-1,0] at intervals of 1:
Line 302 ⟶ 849:
 
=={{header|C}}==
<langsyntaxhighlight Clang="c">#include <stdio.h>
 
double#define mapRange(double a1,double a2,double b1,double b2,doubles) (b1 + (s-a1)*(b2-b1)/(a2-a1))
{
return b1 + (s-a1)*(b2-b1)/(a2-a1);
}
 
int main()
Line 321 ⟶ 865:
return 0;
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 338 ⟶ 882:
 
=={{header|C sharp}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Linq;
 
Line 349 ⟶ 893:
static double Map(double a1, double a2, double b1, double b2, double s) => b1 + (s - a1) * (b2 - b1) / (a2 - a1);
}</langsyntaxhighlight>
{{out}}
<pre>
Line 369 ⟶ 913:
It's not written efficiently; certainly, there can be fewer explicit temporary variables. The use of the template offers a choice in types for precision and accuracy considerations, though one area for improvement might be to allow a different type for intermediate calculations.
 
<langsyntaxhighlight lang="cpp">#include <iostream>
#include <utility>
 
Line 394 ⟶ 938:
 
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 414 ⟶ 958:
{{trans|Python}}
 
<langsyntaxhighlight lang="clojure">
(defn maprange [[a1 a2] [b1 b2] s]
(+ b1 (/ (* (- s a1) (- b2 b1)) (- a2 a1))))
Line 432 ⟶ 976:
9 maps to -1/10
10 maps to 0
</syntaxhighlight>
</lang>
 
=={{header|COBOL}}==
{{works with|OpenCOBOL}}
<langsyntaxhighlight lang="cobol"> IDENTIFICATION DIVISION.
PROGRAM-ID. demo-map-range.
 
Line 488 ⟶ 1,032:
/ (a-end - a-begin))
.
END PROGRAM map-range.</langsyntaxhighlight>
 
The output is identical to the output of the Common Lisp example.
Line 494 ⟶ 1,038:
=={{header|CoffeeScript}}==
 
<syntaxhighlight lang="coffeescript ">
<lang CoffeeScript >
mapRange = (a1,a2,b1,b2,s) ->
t = b1 + ((s-a1)*(b2 - b1)/(a2-a1))
Line 500 ⟶ 1,044:
for s in [0..10]
console.log("#{s} maps to #{mapRange(0,10,-1,0,s)}")
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 517 ⟶ 1,061:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun map-range (a1 a2 b1 b2 s)
(+ b1
(/ (* (- s a1)
Line 527 ⟶ 1,071:
do (format t "~F maps to ~F~C" i
(map-range 0 10 -1 0 i)
#\Newline))</langsyntaxhighlight>
 
{{out}}
Line 542 ⟶ 1,086:
10.0 maps to 0.0</pre>
 
=={{header|Craft Basic}}==
<syntaxhighlight lang="basic">define a1 = 0, b1 = 0, a2 = 0, b2 = 0
 
for i = 0 to 10
 
let s = i
let a1 = 0
let a2 = 10
let b1 = -1
let b2 = 0
 
print i, " : ", b1 + ( s - a1 ) * ( b2 - b1 ) / ( a2 - a1 )
 
next i</syntaxhighlight>
{{out| Output}}<pre>0 : -1
1 : -0.9000
2 : -0.8000
3 : -0.7000
4 : -0.6000
5 : -0.5000
6 : -0.4000
7 : -0.3000
8 : -0.2000
9 : -0.1000
10 : 0</pre>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">double mapRange(in double[] a, in double[] b, in double s)
pure nothrow @nogc {
return b[0] + ((s - a[0]) * (b[1] - b[0]) / (a[1] - a[0]));
Line 556 ⟶ 1,125:
foreach (immutable s; 0 .. 11)
writefln("%2d maps to %5.2f", s, mapRange(r1, r2, s));
}</langsyntaxhighlight>
{{out}}
<pre> 0 maps to -1.00
Line 569 ⟶ 1,138:
9 maps to -0.10
10 maps to 0.00</pre>
=={{header|Delphi}}==
See [[#Pascal]].
=={{header|EasyLang}}==
<syntaxhighlight>
func map_range a1 a2 b1 b2 s .
return b1 + (s - a1) * (b2 - b1) / (a2 - a1)
.
for i = 0 to 10
print i & " -> " & map_range 0 10 -1 0 i
.
</syntaxhighlight>
{{out}}
<pre>
0 -> -1
1 -> -0.90
2 -> -0.80
3 -> -0.70
4 -> -0.60
5 -> -0.50
6 -> -0.40
7 -> -0.30
8 -> -0.20
9 -> -0.10
10 -> 0
</pre>
 
=={{header|EchoLisp}}==
EchoLisp provides several native interpolation functions: smoothstep, s-curve, .. and '''linear''' which performs linear interpolation.
<langsyntaxhighlight lang="scheme">
(lib 'plot) ;; interpolation functions
(lib 'compile)
Line 603 ⟶ 1,197:
8 -1/5 -0.2
9 -1/10 -0.1
</syntaxhighlight>
</lang>
 
=={{header|Elixir}}==
<langsyntaxhighlight lang="elixir">defmodule RC do
def map_range(a1 .. a2, b1 .. b2, s) do
b1 + (s - a1) * (b2 - b1) / (a2 - a1)
Line 614 ⟶ 1,208:
Enum.each(0..10, fn s ->
:io.format "~2w map to ~7.3f~n", [s, RC.map_range(0..10, -1..0, s)]
end)</langsyntaxhighlight>
 
{{out}}
Line 632 ⟶ 1,226:
 
=={{header|Emacs Lisp}}==
<langsyntaxhighlight lang="lisp">(defun maprange (a1 a2 b1 b2 s)
(+ b1 (/ (* (- s a1) (- b2 b1)) (- a2 a1))))
(dotimes (i 10)
(princmessage "%s" (maprange 0.0 10.0 -1.0 0.0 i)))</syntaxhighlight>
(terpri))</lang>
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">-module(map_range).
-export([map_value/3]).
 
map_value({A1,A2},{B1,B2},S) ->
B1 + (S - A1) * (B2 - B1) / (A2 - A1).
</syntaxhighlight>
</lang>
 
=={{header|ERRE}}==
<langsyntaxhighlight ERRElang="erre">PROGRAM RANGE
 
BEGIN
Line 659 ⟶ 1,252:
END FOR
END PROGRAM
</syntaxhighlight>
</lang>
{{out}}
<pre> 0 maps to -1.00
Line 675 ⟶ 1,268:
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">function map_range(sequence a, sequence b, atom s)
return b[1]+(s-a[1])*(b[2]-b[1])/(a[2]-a[1])
end function
Line 681 ⟶ 1,274:
for i = 0 to 10 do
printf(1, "%2g maps to %4g\n", {i, map_range({0,10},{-1,0},i)})
end for</langsyntaxhighlight>
 
{{out}}
Line 696 ⟶ 1,289:
10 maps to 0
</pre>
 
=={{header|F#}}==
<syntaxhighlight lang="fsharp">
let map (a1: float) (a2: float) (b1: float) (b2: float) (s: float): float =
b1 + (s - a1) * (b2 - b1) / (a2 - a1)
 
let xs = [| for i in 0..10 -> map 0.0 10.0 -1.0 0.0 (float i) |]
 
for x in xs do printfn "%f" x
</syntaxhighlight>
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USE: locals
:: map-range ( a1 a2 b1 b2 x -- y )
x a1 - b2 b1 - * a2 a1 - / b1 + ;</langsyntaxhighlight>
Or:
<langsyntaxhighlight lang="factor">USING: locals infix ;
:: map-range ( a1 a2 b1 b2 x -- y )
[infix
b1 + (x - a1) * (b2 - b1) / (a2 - a1)
infix] ;</langsyntaxhighlight>
Test run:
<langsyntaxhighlight lang="factor">10 iota [| x | 0 10 -1 0 x map-range ] map . ! { -1 -9/10 -4/5 -7/10 -3/5 -1/2 -2/5 -3/10 -1/5 -1/10 }</langsyntaxhighlight>
 
=={{header|Fantom}}==
 
<langsyntaxhighlight lang="fantom">
class FRange
{
Line 746 ⟶ 1,350:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 764 ⟶ 1,368:
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">\ linear interpolation
 
: lerp ( b2 b1 a2 a1 s -- t )
Line 772 ⟶ 1,376:
f+ ;
 
: test 11 0 do 0e -1e 10e 0e i s>f lerp f. loop ;</langsyntaxhighlight>
 
There is less stack shuffling if you use origin and range instead of endpoints for intervals. (o = a1, r = a2-a1)
 
<langsyntaxhighlight lang="forth">: lerp ( o2 r2 r1 o1 s -- t ) fswap f- fswap f/ f* f+ ;
 
: test 11 0 do -1e 1e 10e 0e i s>f lerp f. loop ;</langsyntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">program Map
implicit none
Line 802 ⟶ 1,406:
 
end function Maprange
end program Map</langsyntaxhighlight>
 
 
=={{header|FreeBASIC}}==
{{trans|Yabasic}}
<syntaxhighlight lang="freebasic">Function MapRange(s As Integer, a1 As Integer, a2 As Integer, b1 As Integer, b2 As Integer) As Double
Return b1+(s-a1)*(b2-b1)/(a2-a1)
End Function
 
For i As Integer = 0 To 10
Print Using "## maps to ##.#"; i; MapRange(i,0,10,-1,0)
Next i
Sleep</syntaxhighlight>
{{out}}
<pre>
0 maps to -1.0
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0.0
</pre>
 
=={{header|Frink}}==
Frink can exactly map to rational numbers so the mapping is round-trippable.
<syntaxhighlight lang="frink">mapRange[s, a1, a2, b1, b2] := b1 + (s-a1)(b2-b1)/(a2-a1)
 
for a = 0 to 10
println["$a\t" + mapRange[a, 0, 10, -1, 0]]</syntaxhighlight>
{{out}}
<pre>
0 -1
1 -9/10 (exactly -0.9)
2 -4/5 (exactly -0.8)
3 -7/10 (exactly -0.7)
4 -3/5 (exactly -0.6)
5 -1/2 (exactly -0.5)
6 -2/5 (exactly -0.4)
7 -3/10 (exactly -0.3)
8 -1/5 (exactly -0.2)
9 -1/10 (exactly -0.1)
10 0
</pre>
 
Much more impressive, though, is that Frink is a powerful Computer Algebra System (CAS) and can symbolically invert the function so you can map t back to s:
 
https://frinklang.org/fsp/solve2.fsp?equations=t+%3D+b1+%2B+%28s-a1%29%28b2-b1%29%2F%28a2-a1%29&solveFor=s&f=on&ev=on&sel_a1=S&val_a1=&sel_a2=S&val_a2=&sel_b1=S&val_b1=&sel_b2=S&val_b2=&sel_t=S&val_t=1000+kg&resultAs=
 
The resulting inverse function is:
<syntaxhighlight lang="frink">inverseMapRange[t, a1, a2, b1, b2] := a1 + a1 b1 (-1 b1 + b2)^-1 + -1 a2 b1 (-1 b1 + b2)^-1 + -1 a1 (-1 b1 + b2)^-1 t + a2 (-1 b1 + b2)^-1 t</syntaxhighlight>
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
 
local fn MapRange( s as double, a1 as double, a2 as double, b1 as double, b2 as double ) as double
end fn = b1+(s-a1)*(b2-b1)/(a2-a1)
 
NSInteger i
 
for i = 0 to 10
NSLog( @"%2d maps to %5.1f", i, fn MapRange( i, 0, 10, -1, 0 ) )
next
 
HandleEvents
</syntaxhighlight>
Output:
<pre>
0 maps to -1.0
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0.0
</pre>
 
=={{header|GDScript}}==
<syntaxhighlight lang="gdscript">func mapRange(s:float, a1:float, a2:float, b1:float, b2:float) -> float :
return b1 + ((b2-b1)/(a2-a1))*(s-a1)
 
for i in 11 :
print( "%2d %+.1f" % [i,mapRange(i,0.0,10.0,-1.0,0.0)] )
</syntaxhighlight>
 
{{out}}
<pre>
0 -1.0
1 -0.9
2 -0.8
3 -0.7
4 -0.6
5 -0.5
6 -0.4
7 -0.3
8 -0.2
9 -0.1
10 +0.0
</pre>
 
 
=={{header|Go}}==
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
 
local fn MapRange( s as double, a1 as double, a2 as double, b1 as double, b2 as double ) as double
end fn = b1+(s-a1)*(b2-b1)/(a2-a1)
 
NSInteger i
 
for i = 0 to 10
NSLog( @"%2d maps to %5.1f", i, fn MapRange( i, 0, 10, -1, 0 ) )
next
 
HandleEvents
</syntaxhighlight>
Output:
<pre>
0 maps to -1.0
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0.0
</pre>
 
=={{header|Go}}==
'''Basic task'''
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 823 ⟶ 1,566:
fmt.Println(n, "maps to", mapRange(r1, r2, n))
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 843 ⟶ 1,586:
Second, ", ok" is a Go idiom. It takes advantage of Go's multiple return values and multiple assignment to return a success/failure disposition.
In the case of this task, the result t is undefined if the input s is out of range.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 879 ⟶ 1,622:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 893 ⟶ 1,636:
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">
def mapRange(a1, a2, b1, b2, s) {
b1 + ((s - a1) * (b2 - b1)) / (a2 - a1)
Line 901 ⟶ 1,644:
println(s + " in [0, 10] maps to " + mapRange(0, 10, -1, 0, s) + " in [-1, 0].")
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 916 ⟶ 1,659:
10 in [0, 10] maps to 0 in [-1, 0].
</pre>
 
=={{header|Haskell}}==
Rather than handling only floating point numbers, the mapping function takes any number implementing the <tt>Fractional</tt> typeclass, which in our example also includes exact <tt>Rational</tt> numbers.
<langsyntaxhighlight lang="haskell">import Data.Ratio
import Text.Printf (PrintfType, printf)
 
Line 945 ⟶ 1,689:
:: PrintfType r
=> Integer -> Rational -> r
prtR n x = printf "%2d -> %s\n" n (show x)</langsyntaxhighlight>
{{out}}
<pre>---------- Floating point ----------
Line 974 ⟶ 1,718:
=={{header|Icon}} and {{header|Unicon}}==
 
<syntaxhighlight lang="unicon">
<lang Unicon>
record Range(a, b)
 
Line 998 ⟶ 1,742:
}
end
</syntaxhighlight>
</lang>
 
Icon does not permit the type declaration, as Unicon does. For Icon, replace 'remap' with:
 
<syntaxhighlight lang="icon">
<lang Icon>
procedure remap (range1, range2, n)
n *:= 1.0
Line 1,008 ⟶ 1,752:
return range1.a + (n - range2.a) * (range1.b - range1.a) / (range2.b - range2.a)
end
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,027 ⟶ 1,771:
=={{header|J}}==
 
<langsyntaxhighlight lang="j">maprange=:2 :0
'a1 a2'=.m
'b1 b2'=.n
b1+((y-a1)*b2-b1)%a2-a1
)
NB. this version defers all calculations to runtime, but mirrors exactly the task formulation</langsyntaxhighlight>
 
Or
 
<langsyntaxhighlight lang="j">maprange=:2 :0
'a1 a2'=.m
'b1 b2'=.n
b1 + ((b2-b1)%a2-a1) * -&a1
)
NB. this version precomputes the scaling ratio</langsyntaxhighlight>
 
Or, more concisely:<syntaxhighlight lang="j">maprange=:{{ ({.n) + (n%&(-/)m) * -&({.m) }}</syntaxhighlight>
 
Example use:
 
<langsyntaxhighlight lang="j"> 2 4 maprange 5 11 (2.718282 3 3.141592)
7.15485 8 8.42478</langsyntaxhighlight>
 
or
 
<langsyntaxhighlight lang="j"> adjust=:2 4 maprange 5 11 NB. save the derived function as a named entity
adjust 2.718282 3 3.141592
7.15485 8 8.42478</langsyntaxhighlight>
 
Required example:
 
<langsyntaxhighlight lang="j"> 0 10 maprange _1 0 i.11
_1 _0.9 _0.8 _0.7 _0.6 _0.5 _0.4 _0.3 _0.2 _0.1 0</langsyntaxhighlight>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">public class Range {
public static void main(String[] args){
for(float s = 0;s <= 10; s++){
Line 1,070 ⟶ 1,817:
return b1 + ((s - a1)*(b2 - b1))/(a2 - a1);
}
}</langsyntaxhighlight>
{{out}}
<pre>0.0 in [0, 10] maps to -1.0 in [-1, 0].
Line 1,084 ⟶ 1,831:
10.0 in [0, 10] maps to 0.0 in [-1, 0].</pre>
The differences in 7, 8, and 9 come from double math. Similar issues show even when using float types.
 
=={{header|JavaScript}}==
===ES5===
<lang JavaScript>// Javascript doesn't have built-in support for ranges
<syntaxhighlight lang="javascript">// Javascript doesn't have built-in support for ranges
// Insted we use arrays of two elements to represent ranges
var mapRange = function(from, to, s) {
Line 1,096 ⟶ 1,845:
}
 
console.log(range);</langsyntaxhighlight>
{{out}}
<pre>[-1, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.30000000000000004, -0.19999999999999996, -0.09999999999999998, 0]</pre>
 
=== =Extra credit ====
Here we will use the [https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map ECMAScript 5 support for map] and the [http://underscorejs.org/#range _.range] function from Underscore.js.
{{libheader|Underscore.js}}
<langsyntaxhighlight JavaScriptlang="javascript">var mapRange = function(from, to, s) {
// mapRange expects ranges generated by _.range
var a1 = from[0];
Line 1,121 ⟶ 1,870:
});
 
console.log(fromRange);</langsyntaxhighlight>
{{out}}
<pre>[-1, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.30000000000000004, -0.19999999999999996, -0.09999999999999998, 0]</pre>
 
===ES6===
 
Composing a solution from generic abstractions:
<syntaxhighlight lang="javascript">(() => {
'use strict';
 
// main :: IO ()
const main = () => {
 
// rangeMap :: (Num, Num) -> (Num, Num) -> Num -> Num
const rangeMap = (a, b) => s => {
const [a1, a2] = a;
const [b1, b2] = b;
// Scaling up an order, and then down, to bypass a potential,
// precision issue with negative numbers.
return (((((b2 - b1) * (s - a1)) / (a2 - a1)) * 10) + (10 * b1)) / 10;
};
 
const
mapping = rangeMap([0, 10], [-1, 0]),
xs = enumFromTo(0, 10),
ys = map(mapping, xs),
zs = map(approxRatio(''), ys);
 
 
const formatted = (x, m, r) => {
const
fract = showRatio(r),
[n, d] = splitOn('/', fract);
return justifyRight(2, ' ', x.toString()) + ' -> ' +
justifyRight(4, ' ', m.toString()) + ' = ' +
justifyRight(2, ' ', n.toString()) + '/' + d.toString();
};
 
console.log(
unlines(zipWith3(formatted, xs, ys, zs))
);
};
 
 
// GENERIC FUNCTIONS ----------------------------
 
// abs :: Num -> Num
const abs = Math.abs;
 
// Epsilon - > Real - > Ratio
// approxRatio :: Real -> Real -> Ratio
const approxRatio = eps => n => {
const
gcde = (e, x, y) => {
const _gcd = (a, b) => (b < e ? a : _gcd(b, a % b));
return _gcd(abs(x), abs(y));
},
c = gcde(Boolean(eps) ? eps : (1 / 10000), 1, abs(n)),
r = ratio(quot(abs(n), c), quot(1, c));
return {
type: 'Ratio',
n: r.n * signum(n),
d: r.d
};
};
 
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
Array.from({
length: 1 + n - m
}, (_, i) => m + i)
 
// gcd :: Int -> Int -> Int
const gcd = (x, y) => {
const
_gcd = (a, b) => (0 === b ? a : _gcd(b, a % b)),
abs = Math.abs;
return _gcd(abs(x), abs(y));
};
 
// justifyRight :: Int -> Char -> String -> String
const justifyRight = (n, cFiller, s) =>
n > s.length ? (
s.padStart(n, cFiller)
) : s;
 
// Returns Infinity over objects without finite length
// this enables zip and zipWith to choose the shorter
// argument when one is non-finite, like cycle, repeat etc
 
// length :: [a] -> Int
const length = xs => Array.isArray(xs) ? xs.length : Infinity;
 
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
 
// quot :: Int -> Int -> Int
const quot = (n, m) => Math.floor(n / m);
 
// ratio :: Int -> Int -> Ratio Int
const ratio = (x, y) => {
const go = (x, y) =>
0 !== y ? (() => {
const d = gcd(x, y);
return {
type: 'Ratio',
'n': quot(x, d), // numerator
'd': quot(y, d) // denominator
};
})() : undefined;
return go(x * signum(y), abs(y));
};
 
// showRatio :: Ratio -> String
const showRatio = nd =>
nd.n.toString() + '/' + nd.d.toString();
 
// signum :: Num -> Num
const signum = n => 0 > n ? -1 : (0 < n ? 1 : 0);
 
// splitOn :: String -> String -> [String]
const splitOn = (pat, src) =>
src.split(pat);
 
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
 
// zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
const zipWith3 = (f, xs, ys, zs) =>
Array.from({
length: Math.min(length(xs), length(ys), length(zs))
}, (_, i) => f(xs[i], ys[i], zs[i]));
 
// MAIN ---
return main();
})();</syntaxhighlight>
{{Out}}
<pre> 0 -> -1 = -1/1
1 -> -0.9 = -9/10
2 -> -0.8 = -4/5
3 -> -0.7 = -7/10
4 -> -0.6 = -3/5
5 -> -0.5 = -1/2
6 -> -0.4 = -2/5
7 -> -0.3 = -3/10
8 -> -0.2 = -1/5
9 -> -0.1 = -1/10
10 -> 0 = 0/1</pre>
 
=={{header|jq}}==
In jq, it is generally preferable to define functions as parameterized filters. In the present case,
since the task calls for defining a map, the signature maprange(a;b), where a and b are the two ranges, is appropriate.
<langsyntaxhighlight lang="jq"># The input is the value to be mapped.
# The ranges, a and b, should each be an array defining the
# left-most and right-most points of the range.
def maprange(a; b):
b[0] + (((. - a[0]) * (b[1] - b[0])) / (a[1] - a[0])) ;</langsyntaxhighlight>
'''Example 1''': a single value
6 | maprange([0,10]; [-1, 0])
Line 1,139 ⟶ 2,033:
 
'''Example 2''': a stream of values
<langsyntaxhighlight lang="jq">range(0;11) | maprange([0,10]; [-1, 0])</langsyntaxhighlight>
produces:
-1
Line 1,154 ⟶ 2,048:
====Extra credit====
To avoid repeating the same arithmetic, we shall define a filter that handles an array of values all at once, using an inner function and map/1:
<langsyntaxhighlight lang="jq">def maprange_array(a; b):
def _helper(a0; b0; factor): b0 + (. - a0) * factor;
 
a[0] as $a | b[0] as $b | ((b[1] - b[0]) / (a[1] - a[0])) as $factor
| map(_helper( $a; $b; $factor) );</langsyntaxhighlight>
'''Example''':
[range(0;11)] | maprange_array([0,10]; [-1, 0])
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
<lang julia>maprange(s, a, b) = let a1 = minimum(a), a2 = maximum(a), b1 = minimum(b), b2 = maximum(b)
b1 + (s-a1) * (b2-b1) / (a2-a1)
end</lang>
By using <code>maximum</code> and <code>minimum</code> in our implementation, we can pass <code>maprange</code> Julia's built-in <code>Range</code> type to represent the ranges ''a'' and ''b'':
<pre>
julia> maprange(6, 0:10, -1:0)
-0.4
 
<syntaxhighlight lang="julia">function maprange([0:10]s, 0:10a, -1:0b)
a₁, a₂ = minimum(a), maximum(a)
11-element Array{Float64,1}:
b₁, b₂ = minimum(b), maximum(b)
-1.0
return b₁ + (s - a₁) * (b₂ - b₁) / (a₂ - a₁)
-0.9
end
-0.8
-0.7
-0.6
-0.5
-0.4
-0.3
-0.2
-0.1
0.0
 
julia>@show maprange(0:106, 01:10, -1:0)
@show maprange(0:10, 0:10, -1:0)</syntaxhighlight>
-1.0:0.1:0.0
 
</pre>
{{out}}
<pre>maprange(6, 1:10, -1:0) = -0.4444444444444444
maprange(0:10, 0:10, -1:0) = -1.0:0.1:0.0</pre>
 
=={{header|K}}==
<langsyntaxhighlight Klang="k"> f:{[a1;a2;b1;b2;s] b1+(s-a1)*(b2-b1)%(a2-a1)}
 
+(a; f[0;10;-1;0]'a:!11)
Line 1,203 ⟶ 2,086:
(8;-0.2)
(9;-0.1)
(10;0.0))</langsyntaxhighlight>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.0.6
 
class FloatRange(override val start: Float, override val endInclusive: Float) : ClosedRange<Float>
Line 1,221 ⟶ 2,104:
println(String.format("%2d maps to %+4.2f", i, mappedValue))
}
}</langsyntaxhighlight>
 
{{out}}
Line 1,237 ⟶ 2,120:
10 maps to +0.00
</pre>
 
=={{header|Lambdatalk}}==
<syntaxhighlight lang="scheme">
{def maprange
{lambda {:a0 :a1 :b0 :b1 :s}
{+ :b0 {/ {* {- :s :a0} {- :b1 :b0}} {- :a1 :a0}}}}}
-> maprange
 
{maprange 0 10 -1 0 5}
-> -0.5
 
{S.map {maprange 0 10 -1 0} {S.serie 0 10}}
->
0 maps to -1
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.30000000000000004
8 maps to -0.19999999999999996
9 maps to -0.09999999999999998
10 maps to 0
</syntaxhighlight>
 
=={{header|Lasso}}==
<langsyntaxhighlight Lassolang="lasso">define map_range(
a1,
a2,
Line 1,253 ⟶ 2,161:
'<br />'
 
^}'</langsyntaxhighlight>
{{out}}
<pre>0: -1.0
Line 1,266 ⟶ 2,174:
9: -0.1
10: 0.0</pre>
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="liberty basic">For i = 0 To 10
Print "f(";i;") maps to ";mapToRange(i, 0, 10, -1, 0)
Next i
End
 
Function mapToRange(value, inputMin, inputMax, outputMin, outputMax)
mapToRange = (((value - inputMin) * (outputMax - outputMin)) / (inputMax - inputMin)) + outputMin
End Function
</syntaxhighlight>
{{out}}
<pre>f(0) maps to -1
f(1) maps to -0.9
f(2) maps to -0.8
f(3) maps to -0.7
f(4) maps to -0.6
f(5) maps to -0.5
f(6) maps to -0.4
f(7) maps to -0.3
f(8) maps to -0.2
f(9) maps to -0.1
f(10) maps to 0</pre>
 
=={{header|Logo}}==
<langsyntaxhighlight lang="logo">to interpolate :s :a1 :a2 :b1 :b2
output (:s-:a1) / (:a2-:a1) * (:b2-:b1) + :b1
end
 
for [i 0 10] [print interpolate :i 0 10 -1 0]</langsyntaxhighlight>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">function map_range( a1, a2, b1, b2, s )
return b1 + (s-a1)*(b2-b1)/(a2-a1)
end
Line 1,281 ⟶ 2,212:
for i = 0, 10 do
print( string.format( "f(%d) = %f", i, map_range( 0, 10, -1, 0, i ) ) )
end</langsyntaxhighlight>
 
=={{header|M2000 Interpreter}}==
 
=== Using Class ===
=={{header|Mathematica}}==
<syntaxhighlight lang="m2000 interpreter">
Such a function is already built in
module MapRange {
<lang Mathematica>
class Map {
Rescale[#,{0,10},{-1,0}]&/@Range[0,10]
private:
</lang>
a, b, f
public:
value (x){
=.b+(x-.a)*.f
}
class:
module Map (.a,a2,.b,b2) {
if a2-.a=0 then error "wrong parameters"
.f<=(b2-.b)/(a2-.a)
}
}
m1=Map(0,10, -1, 0)
for i=0 to 10
Print i," maps to ";m1(i)
next
}
MapRange
</syntaxhighlight>
 
=== Using Lambda ===
 
<syntaxhighlight lang="m2000 interpreter">
module MapRange {
Map=lambda (a,a2,b,b2) -> {
if a2-a=0 then error "wrong parameters"
f=(b2-b)/(a2-a)
=lambda a,b,f (x)->b+(x-a)*f
}
m1=Map(0,10, -1, 0)
for i=0 to 10
Print i," maps to ";m1(i)
next
}
MapRange
</syntaxhighlight>
 
Same output for both versions
 
{{out}}
<pre>
0 maps to -1
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0
</pre>
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">
Map:=proc(a1,a2,b1,b2,s);
return (b1+((s-a1)*(b2-b1)/(a2-a1)));
end proc;
 
for i from 0 to 10 do
printf("%a maps to ",i);
printf("%a\n",Map(0,10,-1,0,i));
end do;
</syntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Such a function is already built in
<syntaxhighlight lang="mathematica">Rescale[#,{0,10},{-1,0}]&/@Range[0,10]</syntaxhighlight>
{{out}}
<pre>{-1., -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.}</pre>
 
=={{header|Maxima}}==
<langsyntaxhighlight lang="maxima">maprange(a, b, c, d) := buildq([e: ratsimp(('x - a)*(d - c)/(b - a) + c)],
lambda([x], e))$
 
f: maprange(0, 10, -1, 0);</langsyntaxhighlight>
 
=={{header|Nemerle}}==
<langsyntaxhighlight Nemerlelang="nemerle">using System;
using System.Console;
 
Line 1,317 ⟶ 2,317:
WriteLine("{0, 2:f0} maps to {1:f1}", i, Maprange((0.0, 10.0), (-1.0, 0.0), i));
}
}</langsyntaxhighlight>
 
=={{header|NetRexx}}==
<langsyntaxhighlight lang="netrexx">/* NetRexx */
options replace format comments java crossref savelog symbols nobinary
 
Line 1,340 ⟶ 2,340:
t_ = b1 + ((s_ - a1) * (b2 - b1) / (a2 - a1))
return t_
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,361 ⟶ 2,361:
{{trans|Python}}
 
<langsyntaxhighlight lang="nim">import strutilsstrformat
 
type FloatRange = tuple[s, e: float]
 
proc mapRange(a, b: FloatRange,; s: float): float =
b.s + (s - a.s) * (b.e - b.s) / (a.e - a.s)
 
for i in 0..10:
let m = mapRange((0.0,10.0), (-1.0, 0.0), float(i))
echo &"{i, ":>2} maps to {m:4.1f}", formatFloat(m, precision = 0)</langsyntaxhighlight>
 
{{out}}
<pre> 0 maps to -1.0
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0.0</pre>
 
=={{header|Objeck}}==
<langsyntaxhighlight lang="objeck">
bundle Default {
class Range {
Line 1,401 ⟶ 2,401:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,421 ⟶ 2,421:
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">let map_range (a1, a2) (b1, b2) s =
b1 +. ((s -. a1) *. (b2 -. b1) /. (a2 -. a1))
Line 1,428 ⟶ 2,428:
for i = 0 to 10 do
Printf.printf "f(%d) = %g\n" i (map_range (0.0, 10.0) (-1.0, 0.0) (float i))
done</langsyntaxhighlight>
 
{{out}}
Line 1,446 ⟶ 2,446:
If range mapping is used in a heavy computational task we can reduce the number of calculations made using partial application and [[currying]]:
 
<langsyntaxhighlight lang="ocaml">let map_range (a1, a2) (b1, b2) =
let v = (b2 -. b1) /. (a2 -. a1) in
function s ->
Line 1,456 ⟶ 2,456:
for i = 0 to 10 do
Printf.printf "f(%d) = %g\n" i (p (float i))
done</langsyntaxhighlight>
 
 
=={{header|Oforth}}==
 
<langsyntaxhighlight Oforthlang="oforth">: mapRange(p1, p2, s)
s p1 first - p2 second p2 first - * p1 second p1 first - asFloat /
p2 first + ;</langsyntaxhighlight>
 
{{out}}
Line 1,474 ⟶ 2,473:
=={{header|PARI/GP}}==
Usage (e.g.): map([1,10],[0,5],8.)
<langsyntaxhighlight lang="parigp">map(r1,r2,x)=r2[1]+(x-r1[1])*(r2[2]-r2[1])/(r1[2]-r1[1])</langsyntaxhighlight>
 
=={{header|Pascal}}==
<langsyntaxhighlight lang="pascal">Program Map(output);
 
function MapRange(fromRange, toRange: array of real; value: real): real;
Line 1,489 ⟶ 2,488:
for i := 0 to 10 do
writeln (i, ' maps to: ', MapRange([0.0, 10.0], [-1.0, 0.0], i):4:2);
end.</langsyntaxhighlight>
{{out}}
<pre>:> ./MapRange
Line 1,517 ⟶ 2,516:
 
Output as above.
<langsyntaxhighlight lang="pascal">Program Map(output);
 
type
Line 1,572 ⟶ 2,571:
MapRecRange(value,mr):10:6);
end;
end.</langsyntaxhighlight>
 
=={{header|Perl}}==
<langsyntaxhighlight Perllang="perl">#!/usr/bin/perl -w
use strict ;
 
Line 1,587 ⟶ 2,586:
my @interval = ( -1 , 0 ) ;
print "The mapped value for $_ is " . mapValue( \@numbers , \@interval , $_ ) . " !\n" foreach @numbers ;
</syntaxhighlight>
</lang>
{{out}}
<PRE>The mapped value for 0 is -1 !
Line 1,601 ⟶ 2,600:
The mapped value for 10 is 0 !
</PRE>
 
=={{header|Perl 6}}==
{{works with|rakudo|2015-09-18}}
<lang perl6>sub the_function(Range $a, Range $b, $s) {
my ($a1, $a2) = $a.bounds;
my ($b1, $b2) = $b.bounds;
return $b1 + (($s-$a1) * ($b2-$b1) / ($a2-$a1));
}
 
for ^11 -> $x { say "$x maps to {the_function(0..10, -1..0, $x)}" }</lang>
 
<pre>%perl6 map_range.p6
0 maps to -1
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0</pre>
A more idiomatic way would be to return a closure that does the mapping without have to supply the ranges every time:
<lang perl6>sub getmapper(Range $a, Range $b) {
my ($a1, $a2) = $a.bounds;
my ($b1, $b2) = $b.bounds;
return -> $s { $b1 + (($s-$a1) * ($b2-$b1) / ($a2-$a1)) }
}
 
my &mapper = getmapper(0 .. 10, -1 .. 0);
for ^11 -> $x {say "$x maps to &mapper($x)"}</lang>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function MapRange(atom s, a1, a2, b1, b2)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
return b1+(s-a1)*(b2-b1)/(a2-a1)
<span style="color: #008080;">function</span> <span style="color: #000000;">map_range</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">a1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">a2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b2</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">b1</span><span style="color: #0000FF;">+(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">-</span><span style="color: #000000;">a1</span><span style="color: #0000FF;">)*(</span><span style="color: #000000;">b2</span><span style="color: #0000FF;">-</span><span style="color: #000000;">b1</span><span style="color: #0000FF;">)/(</span><span style="color: #000000;">a2</span><span style="color: #0000FF;">-</span><span style="color: #000000;">a1</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
for i=0 to 10 by 2 do
printf(1,"%2d : %g\n",{i,MapRange(i,0,10,-1,0)})
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">by</span> <span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
end for</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%2d : %g\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">map_range</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,653 ⟶ 2,623:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(scl 1)
 
(de mapRange (Val A1 A2 B1 B2)
Line 1,661 ⟶ 2,631:
(for Val (range 0 10.0 1.0)
(prinl
(format (mapRange Val 0 10.0 -1.0 0) *Scl) ) )</langsyntaxhighlight>
{{out}}
<pre>-1.0
Line 1,676 ⟶ 2,646:
 
=={{header|PL/I}}==
<langsyntaxhighlight lang="pli">
map: procedure options (main); /* 24/11/2011 */
declare (a1, a2, b1, b2) float;
Line 1,690 ⟶ 2,660:
end map;
end map;
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,709 ⟶ 2,679:
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Group-Range
{
Line 1,746 ⟶ 2,716:
}
}
</syntaxhighlight>
</lang>
<syntaxhighlight lang="powershell">
<lang PowerShell>
0..10 | Group-Range (0,10) (-1,0)
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,768 ⟶ 2,738:
 
=={{header|PureBasic}}==
<langsyntaxhighlight lang="purebasic">Structure RR
a.f
b.f
Line 1,790 ⟶ 2,760:
PrintN(RSet(Str(i),2)+" maps to "+StrF(MapRange(@Range1, @Range2, i),1))
Next
EndIf</langsyntaxhighlight>
<pre> 0 maps to -1.0
1 maps to -0.9
Line 1,804 ⟶ 2,774:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">>>> def maprange( a, b, s):
(a1, a2), (b1, b2) = a, b
return b1 + ((s - a1) * (b2 - b1) / (a2 - a1))
Line 1,822 ⟶ 2,792:
8 maps to -0.2
9 maps to -0.1
10 maps to 0</langsyntaxhighlight>
 
Because of Pythons strict, dynamic, typing rules for numbers the same function can give answers as fractions:
<langsyntaxhighlight lang="python">>>> from fractions import Fraction
>>> for s in range(11):
print("%2g maps to %s" % (s, maprange( (0, 10), (-1, 0), Fraction(s))))
Line 1,841 ⟶ 2,811:
9 maps to -1/10
10 maps to 0
>>> </langsyntaxhighlight>
 
=={{header|Quackery}}==
 
As Quackery does not support reals (or floating point), the function takes the argument s as a decimal string, and returns the result, t as a rational number.
 
<syntaxhighlight lang="Quackery"> [ $ "bigrat.qky" loadfile ] now!
 
[ do over -
2swap
do over -
unrot
dip [ $->v drop ]
n->v v-
rot n->v v/
rot n->v v*
rot n->v v+ ] is maprange ( $ [ [ --> n/d )
 
$ "0 1 2 3 4 5 6 7 8 9 10"
nest$
witheach
[ dup echo$ say " maps to "
' [ 0 10 ] ' [ -1 0 ] maprange
7 point$ echo$ cr ]</syntaxhighlight>
 
{{out}}
 
<pre>0 maps to -1
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0</pre>
 
=={{header|R}}==
<syntaxhighlight lang="rsplus">tRange <- function(aRange, bRange, s)
{
#Guard clauses. We could write some proper error messages, but this is all we really need.
stopifnot(length(aRange) == 2, length(bRange) == 2,
is.numeric(aRange), is.numeric(bRange), is.numeric(s),
s >= aRange[1], s <= aRange[2])
bRange[1] + ((s - aRange[1]) * (bRange[2] - bRange[1])) / (aRange[2] - aRange[1])
}
data.frame(s = 0:10, t = sapply(0:10, tRange, aRange = c(0, 10), bRange = c(-1, 0)))</syntaxhighlight>
{{out}}
<pre> s t
1 0 -1.0
2 1 -0.9
3 2 -0.8
4 3 -0.7
5 4 -0.6
6 5 -0.5
7 6 -0.4
8 7 -0.3
9 8 -0.2
10 9 -0.1
11 10 0.0</pre>
 
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
 
Line 1,856 ⟶ 2,887:
(define map (make-range-map 0 10 -1 0))
(for ([i (in-range 0 11)]) (printf "~a --> ~a\n" i (map i)))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,871 ⟶ 2,902:
9 --> -0.1
10 --> 0.0
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
Return a closure that does the mapping without have to supply the ranges every time.
<syntaxhighlight lang="raku" line>sub getmapper(Range $a, Range $b) {
my ($a1, $a2) = $a.bounds;
my ($b1, $b2) = $b.bounds;
return -> $s { $b1 + (($s-$a1) * ($b2-$b1) / ($a2-$a1)) }
}
 
my &mapper = getmapper(0 .. 10, -1 .. 0);
for ^11 -> $x {say "$x maps to &mapper($x)"}</syntaxhighlight>
{{out}}
<pre>0 maps to -1
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0</pre>
 
=={{header|ReScript}}==
<syntaxhighlight lang="rescript">let map_range = ((a1, a2), (b1, b2), s) => {
b1 +. ((s -. a1) *. (b2 -. b1) /. (a2 -. a1))
}
 
Js.log("Mapping [0,10] to [-1,0] at intervals of 1:")
 
for i in 0 to 10 {
Js.log("f(" ++ Js.String.make(i) ++ ") = " ++
Js.String.make(map_range((0.0, 10.0), (-1.0, 0.0), float(i))))
}</syntaxhighlight>
 
<syntaxhighlight lang="html"><!DOCTYPE html>
<html>
<head>
<title>ReScript: Map_range</title>
<meta charset="UTF-8"/>
<style rel="stylesheet" type="text/css">
body { color:#EEE; background-color:#888; }
</style>
<script>var exports = {};</script>
<script src="./maprange.js"></script>
</head>
<body>
 
</body>
</html></syntaxhighlight>
 
{{out}}
<pre>
Mapping [0,10] to [-1,0] at intervals of 1:
f(0) = -1
f(1) = -0.9
f(2) = -0.8
f(3) = -0.7
f(4) = -0.6
f(5) = -0.5
f(6) = -0.4
f(7) = -0.30000000000000004
f(8) = -0.19999999999999996
f(9) = -0.09999999999999998
f(10) = 0
</pre>
 
=={{header|REXX}}==
(The differentfirst three REXX versions don't differ idiomatically that much, but differ mostly just in style.)
 
The first three versions support different increments &nbsp; (the &nbsp; '''inc''' &nbsp; variable) &nbsp; and an &nbsp; '''A''' &nbsp; range that is decreasing in values
<br>(that is, the 2nd number [usually the high] in the range is less than the first number in the range [usually the low]). &nbsp; Also,
<br>the &nbsp; '''BY''' &nbsp; (increment) &nbsp; is automatically adjusted &nbsp; (either &nbsp; ''upwards'' &nbsp; or &nbsp; ''downwards''). &nbsp; Also,
both sets of numbers in the
<br>output are aligned &nbsp;(vertically).
 
The first three versions support different increments &nbsp; (the &nbsp; '''inc''' &nbsp; varaible) &nbsp; and an &nbsp; '''A''' &nbsp; range that is decreasing in values
<br>(that is, the 2nd number [usually the high] in the range is less than the first number in the range [usually the low]).
===version 1===
<langsyntaxhighlight lang="rexx">/*REXX program maps and displays a range of numbers from one range to another range.*/
rangeA = 0 10 10 /*or: rangeA = ' 0 10 ' */
rangeB = -1 0 0 /*or: rangeB = " -1 0 " */
parse var RangeA rangeA L H
inc= 1
do j=L to H by inc * (1 - 2 * sign(H<L) ) /*BY: either +inc or -inc */
say right(j, digits()9) ' maps to ' mapRangemapR(rangeA, rangeB, j)
end /*j*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
mapRangemapR: procedure; parse arg a1 a2,b1 b2,s; return $=b1 + (s-a1) * (b2-b1) / (a2-a1);return left('',$>=0)$</langsyntaxhighlight>
'''{{out|output'''}}
<pre>
0 maps to -1
Line 1,902 ⟶ 3,005:
8 maps to -0.2
9 maps to -0.1
10 maps to 0 0
</pre>
 
Line 1,909 ⟶ 3,012:
 
Note that this REXX version also uses a different &nbsp; '''rangeA''' &nbsp; numbers &nbsp; (they are reversed).
<langsyntaxhighlight lang="rexx">/*REXX program maps and displays a range of numbers from one range to another range.*/
rangeA = 10 0 /*or: rangeA = ' 10 0 010 ' */
rangeB = -1 0 0 /*or: rangeB = " -1 0 " */
parse var rangeA L H
parse var RangeA L H /*note the LOW & HIGH values in A*/
inc= 1/2
inc= 1/2 /*use a different step size (inc)*/
do j=L to H by inc * (1 - 2 * sign(H<L) ) /*BY: either +inc or -inc */
say right(j, digits()9) ' maps to ' mapRangemapR(rangeA, rangeB, j)
end /*j*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
mapRangemapR: procedure; parse arg a1 a2,b1 b2,s; return $=b1 + (s-a1) * (b2-b1) / (a2-a1);return left('',$>=0)$</langsyntaxhighlight>
'''{{out|output'''}}
<pre>
10 0 maps to -1 0
9.5 maps to -0.95
9.0 maps to -0.9
8.5 maps to -0.85
8.0 maps to -0.8
7.5 maps to -0.75
7.0 maps to -0.7
6.5 maps to -0.65
6.0 maps to -0.6
5.5 maps to -0.55
5.0 maps to -0.5
4.5 maps to -0.45
4.0 maps to -0.4
3.5 maps to -0.35
3.0 maps to -0.3
2.5 maps to -0.25
2.0 maps to -0.2
1.5 maps to -0.15
1.0 maps to -0.1
0.5 maps to -0.05
1.0 maps to -0.1
1.5 maps to -0.15
2.0 maps to -0.2
2.5 maps to -0.25
3.0 maps to -0.3
3.5 maps to -0.35
4.0 maps to -0.4
4.5 maps to -0.45
5.0 maps to -0.5
5.5 maps to -0.55
6.0 maps to -0.6
6.5 maps to -0.65
7.0 maps to -0.7
7.5 maps to -0.75
8.0 maps to -0.8
8.5 maps to -0.85
9.0 maps to -0.9
9.5 maps to -0.95
10.0 maps to -1
</pre>
 
===version 3===
This REXX version showsused a function that calculates and showsalso displays the range mapping.
<langsyntaxhighlight lang="rexx">/*REXX program maps and displays a range of numbers from one range to another range.*/
rangeA = 0 10
rangeB = -1 0
inc = 1
call mapRangemapR rangeA, RangeBrangeB, inc
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
mapRangemapR: procedure; parse arg a1 a2, b1 b2, inc /* [↓] BY: is either +inc or -inc.*/
do s=a1 to a2 by inc * (1 - 2 * sign(a2 < a1) )
say right(s,digits()) ' maps to ' t= b1 + (s-a1) * (b2-b1) / (a2-a1)
end /* say right(s*/, 9) ' maps to' left('', t>=0) /*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/t
end /*s*/
return /*═══════════════t═══════════════*/</lang>
return /* [↑] LEFT··· aligns non─negative #'s*/</syntaxhighlight>
'''output''' &nbsp; is the same as the 1<sup>st</sup> REXX version.
{{out|output|text=&nbsp; is identical to the 1<sup>st</sup> REXX version.}} <br><br>
 
===Version 4===
<langsyntaxhighlight lang="rexx">/*REXX program maps a number from one range to another range. */
/* 31.10.2013 Walter Pachl */
/* 'translated' from an older version 1 without using Procedure */
do j=0 to 10
say right(j,3) ' maps to ' mapRange(0,10,-1,0,j)
Line 1,971 ⟶ 3,075:
/*──────────────────────────────────MAPRANGE subroutine─────────────────*/
mapRange: return arg(3)+(arg(5)-arg(1))*(arg(4)-arg(3))/(arg(2)-arg(1))
/* Arguments are arg a1,a2,b1,b2,x */</langsyntaxhighlight>
{{out}}
<pre>
Almost identical to Version 1
0 maps to -1
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
{{incomplete|Ring|What maps to what in output?}}
<lang ring>
# Project : Map range
# Date : 2017/09/20
# Author : Gal Zsolt (~ CalmoSoft ~)
# Email : <calmosoft@gmail.com>
 
decimals(1)
al = 0
ah = 10
Line 1,988 ⟶ 3,101:
bh = 0
for n = 0 to 10
see "" + n + " maps to " + maprange(al, bl, n) + nl
next
func maprange(al, bl, s)
return bl + (s - al) * (bh - bl) / (ah - al)
</syntaxhighlight>
</lang>
Output:
<pre>
0 maps to -1
1 maps to -0.909
2 maps to -0.808
3 maps to -0.707
4 maps to -0.606
5 maps to -0.505
6 maps to -0.404
7 maps to -0.303
8 maps to -0.202
9 maps to -0.101
10 maps to 0
</pre>
 
=={{header|RPL}}==
Ranges are entered as complex numbers to ease input and shorten code
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪ → ra rb s
≪ rb ra - DUP RE SWAP IM /
s ra RE - * rb RE +
≫ ≫ 'MAP' STO
|
''( (a1, a2) (b1, b2) s -- t )''
Get (b2 - b1)/(a2 - a1)
Multiply by (s - a1) and add b1
|}
{{in}}
<pre>
(0,10) (-1,0) 0 MAP
(0,10) (-1,0) 4 MAP
(0,10) (-1,0) 10 MAP
</pre>
{{out}}
<pre>
3: -1
2: -0.6
1: 0
</pre>
===Basic RPL code===
No specific data structure, no local variable, full stack calculation. Shorter, but less practical in use and difficult to read.
≪ SWAP 3 PICK -
SWAP 5 PICK - *
ROT 4 ROLL - / +
≫ 'MAP' STO
{{in}}
<pre>
0 10 -1 0 0 MAP
0 10 -1 0 4 MAP
0 10 -1 0 10 MAP
</pre>
{{out}}
<pre>
3: -1
2: -0.6
1: 0
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">def map_range(a, b, s)
af, al, bf, bl = a.first, a.last, b.first, b.last
bf + (s - af)*(bl - bf).quo(al - af)
end
 
(0..10).each{|s| puts "%s maps to %g" % [s, map_range(0..10, -1..0, s)]}</langsyntaxhighlight>
 
Numeric#quo does floating point division.
Line 2,034 ⟶ 3,196:
 
To use rational arithmetic, delete <code>s *= 1.0</code> and either <code>require 'rational'</code>, or use Ruby 1.9 (which has Rational in the core library).
<langsyntaxhighlight lang="ruby">(0..10).each do |s|
puts "%s maps to %s" % [s, map_range(0..10, -1..0, s)]
end</langsyntaxhighlight>
 
{{out}} using rational arithmetic:
Line 2,054 ⟶ 3,216:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">use std::f64ops::{Add, Sub, Mul, Div};
 
fn map_range<T: Copy>(from_range: (f64T, f64T), to_range: (f64T, f64T), s: f64T) -> f64T {
where T: Add<T, Output=T> +
Sub<T, Output=T> +
Mul<T, Output=T> +
Div<T, Output=T>
{
to_range.0 + (s - from_range.0) * (to_range.1 - to_range.0) / (from_range.1 - from_range.0)
}
Line 2,066 ⟶ 3,233:
.collect::<Vec<f64>>();
print!("{:?}", result);
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,073 ⟶ 3,240:
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">def mapRange(a1:Double, a2:Double, b1:Double, b2:Double, x:Double):Double=b1+(x-a1)*(b2-b1)/(a2-a1)
 
for(i <- 0 to 10)
println("%2d in [0, 10] maps to %5.2f in [-1, 0]".format(i, mapRange(0,10, -1,0, i)))</langsyntaxhighlight>
{{out}}
<pre> 0 in [0, 10] maps to -1,00 in [-1, 0]
Line 2,091 ⟶ 3,258:
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "float.s7i";
 
Line 2,105 ⟶ 3,272:
writeln("f(" <& number <& ") = " <& mapRange(0.0, 10.0, -1.0, 0.0, flt(number)) digits 1);
end for;
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,124 ⟶ 3,291:
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func map_range(a, b, x) {
var (a1, a2, b1, b2) = (a.bounds, b.bounds);
x-a1 * b2-b1 / a2-a1 + b1;
Line 2,134 ⟶ 3,301:
for x in a {
say "#{x} maps to #{map_range(a, b, x)}";
}</langsyntaxhighlight>
{{out}}
<pre>0 maps to -1
Line 2,147 ⟶ 3,314:
9 maps to -0.1
10 maps to 0</pre>
 
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "mapping" )
@( description, "The task is to write a function/subroutine/... that takes" )
@( description, "two ranges and a real number, and returns the mapping of" )
@( description, "the real number from the first to the second range. Use" )
@( description, "this function to map values from the range [0, 10] to the" )
@( description, "range [-1, 0]." )
@( see_also, "http://rosettacode.org/wiki/Map_range" )
@( author, "Ken O. Burtch" );
pragma license( unrestricted );
 
pragma restriction( no_external_commands );
 
procedure mapping is
type first_range is new float;
type second_range is new float;
-- Spar doesn't implement ranges so we'll use constants
first_range_first : constant first_range := 0.0;
first_range_last : constant first_range := 10.0;
second_range_first : constant second_range := -1.0;
second_range_last : constant second_range := 0.0;
 
function translate (first_range_value : first_range) return second_range is
b1 : constant float := float( second_range_first );
b2 : constant float := float( second_range_last );
a1 : constant float := float( first_range_first );
a2 : constant float := float( first_range_last );
result : float;
begin
result := b1 + (float (first_range_value) - a1) * (b2 - b1) / (a2 - a1);
return second_range(result);
end translate;
 
function translate_back (second_range_value : second_range) return first_range is
b1 : constant float := float (first_range_first);
b2 : constant float := float (first_range_last);
a1 : constant float := float (second_range_first);
a2 : constant float := float (second_range_last);
result : float;
begin
result := b1 + (float (second_range_value) - a1) * (b2 - b1) / (a2 - a1);
return first_range (result);
end translate_back;
 
test_value : first_range := first_range_first;
translated_value : second_range;
translated_back_value : first_range;
begin
loop
translated_value := translate( test_value );
translated_back_value := translate_back( translated_value );
 
? strings.image(test_value) & " maps to: "
& strings.image (translated_value);
? strings.image(translated_value) & " maps back to: "
& strings.image (translated_back_value);
exit when test_value = first_range_last;
test_value := @ + 1.0;
end loop;
end mapping;</syntaxhighlight>
{{out}}
<pre>
$ spar mapping.sp
0.0 maps to: -1.00000000000000E+00
-1.00000000000000E+00 maps back to: 0.00000000000000E+00
1.00000000000000E+00 maps to: -9.00000000000000E-01
-9.00000000000000E-01 maps back to: 1.00000000000000E+00
2.00000000000000E+00 maps to: -8.00000000000000E-01
-8.00000000000000E-01 maps back to: 2.00000000000000E+00
3.00000000000000E+00 maps to: -7.00000000000000E-01
-7.00000000000000E-01 maps back to: 3.00000000000000E+00
4.00000000000000E+00 maps to: -6.00000000000000E-01
-6.00000000000000E-01 maps back to: 4.00000000000000E+00
5.00000000000000E+00 maps to: -5.00000000000000E-01
-5.00000000000000E-01 maps back to: 5.00000000000000E+00
6.00000000000000E+00 maps to: -4.00000000000000E-01
-4.00000000000000E-01 maps back to: 6.00000000000000E+00
7.00000000000000E+00 maps to: -3.00000000000000E-01
-3.00000000000000E-01 maps back to: 7.00000000000000E+00
8.00000000000000E+00 maps to: -2.00000000000000E-01
-2.00000000000000E-01 maps back to: 8.00000000000000E+00
9.00000000000000E+00 maps to: -1.00000000000000E-01
-1.00000000000000E-01 maps back to: 9.00000000000000E+00
1.00000000000000E+01 maps to: 0.00000000000000E+00
0.00000000000000E+00 maps back to: 1.00000000000000E+01</pre>
=={{header|Stata}}==
The following program will map a variable to a new variable. It accepts '''if''' and '''in''' conditions.
 
<syntaxhighlight lang="stata">program define maprange
version 15.1
syntax varname(numeric) [if] [in], ///
from(numlist min=2 max=2) to(numlist min=2 max=2) ///
GENerate(name) [REPLACE]
tempname a b c d h
sca `a'=`:word 1 of `from''
sca `b'=`:word 2 of `from''
sca `c'=`:word 1 of `to''
sca `d'=`:word 2 of `to''
sca `h'=(`d'-`c')/(`b'-`a')
cap confirm variable `generate'
if "`replace'"=="replace" & !_rc {
qui replace `generate'=(`varlist'-`a')*`h'+`c' `if' `in'
}
else {
if "`replace'"=="replace" {
di in gr `"(note: variable `generate' not found)"'
}
qui gen `generate'=(`varlist'-`a')*`h'+`c' `if' `in'
}
end</syntaxhighlight>
 
'''Example'''
 
<syntaxhighlight lang="stata">clear
set obs 11
gen x=_n-1
maprange x if mod(x,2)==0, gen(y) from(0 10) to(-10 10)
maprange x if mod(x,2)!=0, gen(y) from(0 10) to(-100 100) replace
list</syntaxhighlight>
 
'''Output'''
 
<pre> +----------+
| x y |
|----------|
1. | 0 -10 |
2. | 1 -80 |
3. | 2 -6 |
4. | 3 -40 |
5. | 4 -2 |
|----------|
6. | 5 0 |
7. | 6 2 |
8. | 7 40 |
9. | 8 6 |
10. | 9 80 |
|----------|
11. | 10 10 |
+----------+</pre>
 
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">import Foundation
 
func mapRanges(_ r1: ClosedRange<Double>, _ r2: ClosedRange<Double>, to: Double) -> Double {
let num = (to - r1.lowerBound) * (r2.upperBound - r2.lowerBound)
let denom = r1.upperBound - r1.lowerBound
return r2.lowerBound + num / denom
}
 
for i in 0...10 {
print(String(format: "%2d maps to %5.2f", i, mapRanges(0...10, -1...0, to: Double(i))))
}</syntaxhighlight>
 
{{out}}
 
<pre> 0 maps to -1.00
1 maps to -0.90
2 maps to -0.80
3 maps to -0.70
4 maps to -0.60
5 maps to -0.50
6 maps to -0.40
7 maps to -0.30
8 maps to -0.20
9 maps to -0.10
10 maps to 0.00</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
proc rangemap {rangeA rangeB value} {
lassign $rangeA a1 a2
lassign $rangeB b1 b2
expr {$b1 + ($value - $a1)*double($b2 - $b1)/($a2 - $a1)}
}</langsyntaxhighlight>
Demonstration (using a curried alias to bind the ranges mapped from and to):
<langsyntaxhighlight lang="tcl">interp alias {} demomap {} rangemap {0 10} {-1 0}
for {set i 0} {$i <= 10} {incr i} {
puts [format "%2d -> %5.2f" $i [demomap $i]]
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,177 ⟶ 3,515:
=={{header|Ursala}}==
The function <code>f</code> is defined using pattern matching and substitution, taking a pair of pairs of interval endpoints and a number as parameters, and returning a number.
<langsyntaxhighlight Ursalalang="ursala">#import flo
 
f((("a1","a2"),("b1","b2")),"s") = plus("b1",div(minus("s","a1"),minus("a2","a1")))
Line 2,183 ⟶ 3,521:
#cast %eL
 
test = f* ((0.,10.),(-1.,0.))-* ari11/0. 10.</langsyntaxhighlight>
{{out}}
<pre><
Line 2,198 ⟶ 3,536:
0.000000e+00></pre>
A more idiomatic way is to define f as a second order function
<langsyntaxhighlight Ursalalang="ursala">f(("a1","a2"),("b1","b2")) "s" = ...</langsyntaxhighlight>
with the same right hand side as above, so that it takes a pair of intervals and returns a function mapping numbers in one interval to numbers in the other.
 
An even more idiomatic way is to use the standard library function <code>plin</code>, which takes an arbitrarily long list of interval endpoints and returns a piecewise linear interpolation function.
 
=={{header|Vala}}==
<syntaxhighlight lang="vala">double map_range(double s, int a1, int a2, int b1, int b2) {
return b1+(s-a1)*(b2-b1)/(a2-a1);
}
 
void main() {
for (int s = 0; s < 11; s++){
print("%2d maps to %5.2f\n", s, map_range(s, 0, 10, -1, 0));
}
}</syntaxhighlight>
 
{{out}}
<pre>
0 maps to -1.00
1 maps to -0.90
2 maps to -0.80
3 maps to -0.70
4 maps to -0.60
5 maps to -0.50
6 maps to -0.40
7 maps to -0.30
8 maps to -0.20
9 maps to -0.10
10 maps to 0.00
</pre>
 
=={{header|WDTE}}==
<syntaxhighlight lang="wdte">let mapRange r1 r2 s =>
+
(at r2 0)
(/
(*
(-
s
(at r1 0)
)
(-
(at r2 1)
(at r2 0)
)
)
(-
(at r1 1)
(at r1 0)
)
)
;
 
let s => import 'stream';
let str => import 'strings';
 
s.range 10
-> s.map (@ enum v => [v; mapRange [0; 10] [-1; 0] v])
-> s.map (@ print v => str.format '{} -> {}' (at v 0) (at v 1) -- io.writeln io.stdout)
-> s.drain
;</syntaxhighlight>
 
{{out}}
<pre>0 -> -1
1 -> -0.9
2 -> -0.8
3 -> -0.7
4 -> -0.6
5 -> -0.5
6 -> -0.4
7 -> -0.3
8 -> -0.2
9 -> -0.1</pre>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var mapRange = Fn.new { |a, b, s| b.from + (s - a.from) * (b.to - b.from) / (a.to - a.from) }
 
var a = 0..10
var b = -1..0
for (s in a) {
var t = mapRange.call(a, b, s)
Fmt.print("$2d maps to $ h", s, t)
}</syntaxhighlight>
 
{{out}}
<pre>
0 maps to -1
1 maps to -0.9
2 maps to -0.8
3 maps to -0.7
4 maps to -0.6
5 maps to -0.5
6 maps to -0.4
7 maps to -0.3
8 maps to -0.2
9 maps to -0.1
10 maps to 0
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes;
 
func real Map(A1, A2, B1, B2, S);
Line 2,216 ⟶ 3,651:
CrLf(0);
];
]</langsyntaxhighlight>
 
{{out}}
Line 2,232 ⟶ 3,667:
10 0.00000
</pre>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">sub MapRange(s, a1, a2, b1, b2)
return b1+(s-a1)*(b2-b1)/(a2-a1)
end sub
for i = 0 to 10 step 2
print i, " : ", MapRange(i,0,10,-1,0)
next</syntaxhighlight>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn mapRange([(a1,a2)], [(b1,b2)], s) // a1a2 is List(a1,a2)
{ b1 + ((s - a1) * (b2 - b1) / (a2 - a1)) }
 
Line 2,240 ⟶ 3,684:
foreach s in ([0.0 .. 10]){
"%2d maps to %5.2f".fmt(s,mapRange(r1,r2, s)).println();
}</langsyntaxhighlight>
{{out}}
<pre>
2,054

edits