Skip to content

Commit 5e8ad68

Browse files
authored
fix #13, allow size to be 65535 (uint16_t) (#14)
- fix #13, allow size to be 65535 (uint16_t) - add patch for possible interpolation under/overflows. - add multi type **multiMapCache<T1, T2>** as it was missing. - update readme.md - update GitHub actions - minor edits
1 parent 56d77a6 commit 5e8ad68

19 files changed

Lines changed: 427 additions & 51 deletions

File tree

.github/workflows/arduino-lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ jobs:
66
runs-on: ubuntu-latest
77
timeout-minutes: 5
88
steps:
9-
- uses: actions/checkout@v4
10-
- uses: arduino/arduino-lint-action@v1
9+
- uses: actions/checkout@v6
10+
- uses: arduino/arduino-lint-action@v2
1111
with:
1212
library-manager: update
1313
compliance: strict

.github/workflows/arduino_test_runner.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ jobs:
66
runTest:
77
runs-on: ubuntu-latest
88
timeout-minutes: 20
9-
109
steps:
11-
- uses: actions/checkout@v4
10+
- uses: actions/checkout@v6
1211
- uses: ruby/setup-ruby@v1
1312
with:
1413
ruby-version: 2.6

.github/workflows/jsoncheck.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ on:
55
paths:
66
- '**.json'
77
pull_request:
8+
paths:
9+
- '**.json'
810

911
jobs:
1012
test:
1113
runs-on: ubuntu-latest
1214
timeout-minutes: 5
1315
steps:
14-
- uses: actions/checkout@v4
16+
- uses: actions/checkout@v6
1517
- name: json-syntax-check
1618
uses: limitusus/json-syntax-check@v2
1719
with:

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

88

9+
## [0.3.0] - 2026-02-23
10+
- fix #13, allow size to be 65535 (uint16_t)
11+
- add patch for possible interpolation under/overflows.
12+
- add multi type **multiMapCache<T1, T2>** as it was missing.
13+
- update readme.md
14+
- update GitHub actions
15+
- minor edits
16+
17+
----
18+
919
## [0.2.1] - 2025-07-17
1020
- update readme.md
1121
- add multiMap_demo.ino

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2011-2025 Rob Tillaart
3+
Copyright (c) 2011-2026 Rob Tillaart
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

MultiMap.h

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
//
33
// FILE: MultiMap.h
44
// AUTHOR: Rob Tillaart
5-
// VERSION: 0.2.1
5+
// VERSION: 0.3.0
66
// DATE: 2011-01-26
77
// PURPOSE: Arduino library for fast non-linear mapping or interpolation of values
88
// URL: https://github.com/RobTillaart/MultiMap
99
// URL: http://playground.arduino.cc/Main/MultiMap
1010

1111

1212

13-
#define MULTIMAP_LIB_VERSION (F("0.2.1"))
13+
#define MULTIMAP_LIB_VERSION (F("0.3.0"))
1414

1515

1616
#include "Arduino.h"
@@ -22,21 +22,23 @@
2222
//
2323
// note: the in array must have increasing values
2424
template<typename T>
25-
T multiMap(T value, T* _in, T* _out, uint8_t size)
25+
T multiMap(T value, T* _in, T* _out, uint16_t size)
2626
{
2727
// output is constrained to out array
2828
if (value <= _in[0]) return _out[0];
2929
if (value >= _in[size-1]) return _out[size-1];
3030

3131
// search right interval
32-
uint8_t pos = 1; // _in[0] already tested
32+
uint16_t pos = 1; // _in[0] already tested
3333
while(value > _in[pos]) pos++;
3434

3535
// this will handle all exact "points" in the _in array
3636
if (value == _in[pos]) return _out[pos];
3737

3838
// interpolate in the right segment for the rest
3939
return (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
40+
// if interpolation overflows use this line
41+
// return T(float(value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1])) + _out[pos-1];
4042
}
4143

4244

@@ -49,7 +51,7 @@ T multiMap(T value, T* _in, T* _out, uint8_t size)
4951
// e.g. 2 2 2 2 2 3 3 3 3 5 5 5 5 5 5 8 8 8 8 5 5 5 5 5
5052
// implements a minimal cache of the lastValue.
5153
template<typename T>
52-
T multiMapCache(T value, T* _in, T* _out, uint8_t size)
54+
T multiMapCache(T value, T* _in, T* _out, uint16_t size)
5355
{
5456
static T lastValue = -1; // possible bug for 1st call
5557
static T cache = -1;
@@ -72,7 +74,7 @@ T multiMapCache(T value, T* _in, T* _out, uint8_t size)
7274
else
7375
{
7476
// search right interval; index 0 _in[0] already tested
75-
uint8_t pos = 1;
77+
uint16_t pos = 1;
7678
while(value > _in[pos]) pos++;
7779

7880
// this will handle all exact "points" in the _in array
@@ -84,6 +86,8 @@ T multiMapCache(T value, T* _in, T* _out, uint8_t size)
8486
{
8587
// interpolate in the right segment for the rest
8688
cache = (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
89+
// if interpolation overflows use this line
90+
// cache = T(float(value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1])) + _out[pos-1];
8791
}
8892
}
8993
return cache;
@@ -99,7 +103,7 @@ T multiMapCache(T value, T* _in, T* _out, uint8_t size)
99103
//
100104
// note: the in array must have increasing values
101105
template<typename T>
102-
T multiMapBS(T value, T* _in, T* _out, uint8_t size)
106+
T multiMapBS(T value, T* _in, T* _out, uint16_t size)
103107
{
104108
// output is constrained to out array
105109
if (value <= _in[0]) return _out[0];
@@ -110,12 +114,14 @@ T multiMapBS(T value, T* _in, T* _out, uint8_t size)
110114
uint16_t upper = size - 1;
111115
while (lower < upper - 1)
112116
{
113-
uint8_t mid = (lower + upper) / 2;
117+
uint16_t mid = (lower + upper) / 2;
114118
if (value >= _in[mid]) lower = mid;
115119
else upper = mid;
116120
}
117-
121+
// interpolate in the right segment for the rest
118122
return (value - _in[lower]) * (_out[upper] - _out[lower]) / (_in[upper] - _in[lower]) + _out[lower];
123+
// if interpolation overflows use this line
124+
// return T(float(value - _in[lower]) * (_out[upper] - _out[lower]) / (_in[upper] - _in[lower])) + _out[lower];
119125
}
120126

121127

@@ -125,7 +131,7 @@ T multiMapBS(T value, T* _in, T* _out, uint8_t size)
125131
//
126132
// note: the in array must have increasing values
127133
template<typename T1, typename T2>
128-
T2 multiMap(T1 value, T1* _in, T2* _out, uint8_t size)
134+
T2 multiMap(T1 value, T1* _in, T2* _out, uint16_t size)
129135
{
130136
// output is constrained to out array
131137
if (value <= _in[0]) return _out[0];
@@ -140,6 +146,60 @@ T2 multiMap(T1 value, T1* _in, T2* _out, uint8_t size)
140146

141147
// interpolate in the right segment for the rest
142148
return (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
149+
// if interpolation overflows use this line
150+
// return T2(float(value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1])) + _out[pos-1];
151+
}
152+
153+
154+
////////////////////////////////////////////////////////////////////////
155+
//
156+
// MULTITYPE TYPE MULTIMAP CACHE - LINEAR SEARCH
157+
//
158+
// note: the in array must have increasing values
159+
// performance optimized version if inputs do not change often
160+
// e.g. 2 2 2 2 2 3 3 3 3 5 5 5 5 5 5 8 8 8 8 5 5 5 5 5
161+
// implements a minimal cache of the lastValue.
162+
template<typename T1, typename T2>
163+
T2 multiMapCache(T1 value, T1* _in, T2* _out, uint16_t size)
164+
{
165+
static T1 lastValue = -1; // possible bug for 1st call
166+
static T2 cache = -1;
167+
168+
if (value == lastValue)
169+
{
170+
return cache;
171+
}
172+
lastValue = value;
173+
174+
// output is constrained to out array
175+
if (value <= _in[0])
176+
{
177+
cache = _out[0];
178+
}
179+
else if (value >= _in[size-1])
180+
{
181+
cache = _out[size-1];
182+
}
183+
else
184+
{
185+
// search right interval; index 0 _in[0] already tested
186+
uint16_t pos = 1;
187+
while(value > _in[pos]) pos++;
188+
189+
// this will handle all exact "points" in the _in array
190+
if (value == _in[pos])
191+
{
192+
cache = _out[pos];
193+
}
194+
else
195+
{
196+
// interpolate in the right segment for the rest
197+
cache = (value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1]) + _out[pos-1];
198+
// if interpolation overflows use this line
199+
// return T2(float(value - _in[pos-1]) * (_out[pos] - _out[pos-1]) / (_in[pos] - _in[pos-1])) + _out[pos-1];
200+
}
201+
}
202+
return cache;
143203
}
144204

145205

@@ -151,7 +211,7 @@ T2 multiMap(T1 value, T1* _in, T2* _out, uint8_t size)
151211
//
152212
// note: the in array must have increasing values
153213
template<typename T1, typename T2>
154-
T2 multiMapBS(T1 value, T1* _in, T2* _out, uint8_t size)
214+
T2 multiMapBS(T1 value, T1* _in, T2* _out, uint16_t size)
155215
{
156216
// output is constrained to out array
157217
if (value <= _in[0]) return _out[0];
@@ -166,8 +226,10 @@ T2 multiMapBS(T1 value, T1* _in, T2* _out, uint8_t size)
166226
if (value >= _in[mid]) lower = mid;
167227
else upper = mid;
168228
}
169-
229+
// interpolate in the right segment for the rest
170230
return (value - _in[lower]) * (_out[upper] - _out[lower]) / (_in[upper] - _in[lower]) + _out[lower];
231+
// if interpolation overflows use this line
232+
// return T2(float(value - _in[lower]) * (_out[upper] - _out[lower]) / (_in[upper] - _in[lower])) + _out[lower];
171233
}
172234

173235

0 commit comments

Comments
 (0)