Математика - отображение чисел

Как мне сопоставить числа, линейно, между a и b, чтобы перейти между c и d.

То есть я хочу, чтобы числа от 2 до 6 соответствовали числам от 10 до 20 ... но мне нужен обобщенный случай.

Мой мозг сгорел.

Двухточечная форма. en.wikipedia.org/wiki/Linear_equation#Two-point_form

kennytm 06.03.2010 21:53
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
102
1
58 838
10

Ответы 10

Разделите, чтобы получить соотношение между размерами двух диапазонов, затем вычтите начальное значение вашего начального диапазона, умножьте на соотношение и добавьте начальное значение вашего второго диапазона. Другими словами,

R = (20 - 10) / (6 - 2)
y = (x - 2) * R + 10

Это равномерно распределяет числа из первого диапазона во втором диапазоне.

Это не работает. Мой диапазон от 1000000000 до 9999999999, а числа могут быть от 1 до 999999999.

Dejell 19.02.2013 13:39

@Odelya Конечно работает. Это достаточно простое математическое преобразование. Вам просто нужно использовать достаточно большой тип числа (bignum или аналогичный). Ваши числа просто слишком велики для 32-битных целых чисел, но, например, 64-битные целые числа будут работать.

Konrad Rudolph 19.02.2013 15:40

Они двухместные. двойной R = (20-10) / (6-2); двойной y = (X - 2) * R + 10;

Dejell 19.02.2013 15:43

@Odelya Та же проблема. Вы должны прочитать о точности с плавающей запятой. Фактически, это обязательное чтение: Что должен знать каждый компьютерный ученый об арифметике с плавающей запятой - если вам нужен тип с плавающей запятой с такими большими числами, вам, возможно, придется использовать числовой тип произвольной точности.

Konrad Rudolph 19.02.2013 15:52

Можете ли вы порекомендовать тип java, который я могу сделать?

Dejell 20.02.2013 14:02

@Odelya В статье, на которую я ссылаюсь, упоминается соответствующий класс Java

Konrad Rudolph 20.02.2013 14:12

Если ваше число X находится между A и B, а вы хотите, чтобы Y находился между C и D, вы можете применить следующее линейное преобразование:

Y = (X-A)/(B-A) * (D-C) + C

Это должно дать вам то, что вы хотите, хотя ваш вопрос немного неоднозначен, поскольку вы также можете отобразить интервал в обратном направлении. Просто следите за делением на ноль, и все будет в порядке.

Для наглядности мне нравится new_value = (old_value - old_bottom) / (old_top - old_bottom) * (new_top - new_bottom) + new_bottom;

ftrotter 02.06.2014 08:25

Есть ли где-нибудь вывод для этого уравнения?

shaveenk 29.10.2016 00:39

@shaveenk это должно быть уравнение линии с Y=f(X)=m*X+b, где m и b были определены одновременно из следующих двух уравнений ограничений, которые являются результатом подстановки значений X и Y в требуемых конечных точках: C=m*A+b и D=m*B+b

Chris Chiasson 09.03.2017 19:57

Мне также пришлось использовать X=A+(A-B)*t, чтобы доказать равенство этого подхода и подхода Питера. t по сути является обезразмериванием X. (t=(X-A)/(A-B))

Chris Chiasson 09.03.2017 21:32

Чтобы изменить направление, формула: ((X-A) / (A-B) * (C-D)) * -1 + D

Corey Levinson 02.12.2018 23:59

Каждый единичный интервал в первом диапазоне занимает (d-c) / (b-a) «пространство» во втором диапазоне.

Псевдо:

var interval = (d-c)/(b-a)
for n = 0 to (b - a)
    print c + n*interval

Как вы будете обрабатывать округление, зависит от вас.

int srcMin = 2, srcMax = 6;
int tgtMin = 10, tgtMax = 20;

int nb = srcMax - srcMin;
int range = tgtMax - tgtMin;
float rate = (float) range / (float) nb;

println(srcMin + " > " + tgtMin);
float stepF = tgtMin;
for (int i = 1; i < nb; i++)
{
  stepF += rate;
  println((srcMin + i) + " > " + (int) (stepF + 0.5) + " (" + stepF + ")");
}
println(srcMax + " > " + tgtMax);

Конечно, с проверкой деления на ноль.

В стороне, это та же проблема, что и при классическом преобразовании целциуса в фаренгейт, когда вы хотите сопоставить диапазон чисел, который от 0 до 100 (C) до 32-212 (F).

Как это ответ?

shinzou 26.10.2017 19:38

Это пример применения вопроса. Многие сталкиваются с этой простой проблемой во вводных классах CS и не считают, что ее решение можно обобщить на другие проблемы. Я пытался добавить контекст к исходному вопросу. На исходный вопрос уже был дан адекватный ответ.

Metro 07.12.2017 23:21

В дополнение к ответу @PeterAllenWebb, если вы хотите отменить результат, используйте следующее:

reverseX = (B-A)*(Y-C)/(D-C) + A

Было бы неплохо иметь эту функциональность в классе java.lang.Math, так как это широко востребованная функция, доступная на других языках. Вот простая реализация:

final static double EPSILON = 1e-12;

public static double map(double valueCoord1,
        double startCoord1, double endCoord1,
        double startCoord2, double endCoord2) {

    if (Math.abs(endCoord1 - startCoord1) < EPSILON) {
        throw new ArithmeticException("/ 0");
    }

    double offset = startCoord2;
    double ratio = (endCoord2 - startCoord2) / (endCoord1 - startCoord1);
    return ratio * (valueCoord1 - startCoord1) + offset;
}

Я сам помещаю этот код здесь в качестве справки на будущее, и, возможно, он кому-то поможет.

если ваш диапазон от [a до b] и вы хотите отобразить его в [c to d], где x - значение, которое вы хотите сопоставить используйте эту формулу (линейное отображение)

double R = (d-c)/(b-a)
double y = c+(x*R)+R
return(y)

https://rosettacode.org/wiki/Map_range

[a1, a2] => [b1, b2]

if s in range of [a1, a2]

then t which will be in range of [b1, b2]

t= b1 + ((s- a1) * (b2-b1))/ (a2-a1)

Где Икс - это число, которое нужно преобразовать из А-B в C-D, а Y - результат: Возьмем линейную формулу интерполяции, лерп (а, б, мм>) = а + (мм> * (б-а)), и поставить C и D вместо а и б, чтобы получить Y = C + (мм> * (D-C) ). Затем вместо мм> поместите (Икс-А) / (B-А), чтобы получить Y = C + (((Икс-А) / (Икс-А) / (RR_R). Это нормальная функция карты, но ее можно упростить. Возьмите кусок (D-C) и поместите его в дивиденд, чтобы получить Y = C + (((Икс-А) * (D-C)) / (RR_43_R_R-RR). Это дает нам еще один элемент, который мы можем упростить, (Икс-А) * (D-C), что равняется (Икс * D) - (Икс * RR_52_R_R_R) - (RR_53_R_R). Вставьте его, и вы получите Y = C + (((Икс * D) - (Икс * C) - (А * D) + (А * D) + (А * RR_66_R). Следующее, что вам нужно сделать, это добавить бит + C. Для этого вы умножаете C на (B-А), чтобы получить ((B * C) - (А * C)), и перемещаете его в делимое, чтобы получить Y_ ((* R_R_R_R_R_ ((* R_R_78) C) - (А * D) + (А * C) + (B * C) - (А * C)) / (B-RR )_91_91_. Это избыточно, содержит как + (А * C), так и - (А * C), которые компенсируют друг друга. Удалите их, и вы получите окончательный результат: Y = ((Икс * D) - (Икс * C) - (А * D) + (B * RR_104_R_R_10) /

TL; DR: стандартная функция отображения, Y = C + (((Икс-А) / (B-А)) * (D-C), может быть упрощено до R_R_R117 (R_R_R117 (R_R_R116) до R_R117 (R_R_R117 (R_R_R116_R_R_R_116) * C) - (А * D) + (B * C)) / (B-А)

Другие вопросы по теме