Как заставить это приложение map() работать по назначению?

map

Я хочу отобразить диапазон значений 0-63 следующим образом:

x       y
0-15  = 0
16-31 = 1
32-47 = 2
48-63 = 3

Однако, используя функцию map y = map(x, 0, 63, 0, 3); возвращает:

x       y
0-15  = 0
16-31 = 0
32-47 = 1
48-63 = 2

Это связано с усечением дробей или с чем-то другим?

Есть ли лучшая альтернатива?

, 👍1

Обсуждение

вы можете использовать y = x / 16, @Michel Keijzers

@MichelKeijzers Отлично, я не думал, что это можно решить так просто! Спасибо за быстрое решение. Несмотря на это, мне все еще любопытна функция map ()..., @Erik


2 ответа


Лучший ответ:

2

map() работает не совсем так, как можно было бы ожидать. Формула такова:

(x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

И все эти значения являются длинными, что является "длинным" целым числом. Таким образом, все операции выполняются как целые числа, и это означает, что вы теряете очень большую точность в вычислениях, так как все десятичные компоненты полностью игнорируются.

Это означает, что вы получаете максимальную отдачу только тогда, когда вводите максимальную отдачу.

Как отмечает Майкл Кейзерс, ваш ожидаемый результат равен x/16 (или x>>4 в побитовой нотации), и это может быть достигнуто с помощью map (), если вы установите максимальный вход равным 48, а не 63.

Однако простой сдвиг вправо на 4 бита (или деление на 16, если компилятор достаточно умен, чтобы реализовать его как сдвиг вправо) является более эффективным решением, поскольку используемая обработка почти незначительна, тогда как умножение и деление-относительно дорогой набор операций.

,

Re “_если компилятор достаточно умен, чтобы реализовать его как правый сдвиг”: он сделает это только в том случае, если разделенное не имеет знака, или если он может убедить себя, что оно никогда не может быть отрицательным., @Edgar Bonet


1

Вы можете попробовать:

y = map(x, 0, 64, 0, 4);

Майенко показал вам формулу, используемую map(). Вы можете проверить, что формула работает хорошо,если вы думаете в терминах полуоткрытых интервалов:

[0, 64) → [0, 4)

Но это все равно гораздо менее эффективно, чем сдвиг битов.

,