EXCEL Разбить целое число на несколько целых чисел

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

Какой самый чистый способ сделать это? Я сделал это, используя сложную комбинацию ОКРУГЛ ВНИЗ и РАНГА, но это не на 100% надежно.

Имея данные, изложенные, как в опубликованном ответе, вы можете использовать =IF(ROW()-1<COUNT($B$2:$B$7),ROUND($A$2*B2/SUM($B$2:$B$7),0)‌​,A$2-SUM(C$1:C1)) в C2 и скопировать вниз - это эффективно округляет все веса, за исключением последнего, на который распределяется влияние любых округлений.

Spectral Instance 27.06.2024 23:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
104
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Попробуйте следующее:


=ROUND($A$2*(B2/SUM(B$2:B$7)),0)

Или: Могу пролить это:

=LET(α,B2:B7,ROUND(A2*α/SUM(α),0))

Это не сработает. В приведенном выше примере рассмотрим, что произойдет, если вы измените последний вес с 60 на 12, в сумме результаты дадут 787, а не 786.

Jakub Szyguła 27.06.2024 15:22

@JakubSzyguła ах да, я обновлю

Mayukh Bhattacharya 27.06.2024 15:28

Чтобы использовать самый простой пример того, как я ожидаю обработки проблемных округлений. Разделение 7 на 6 частей с одинаковым весом должно дать 2 1 1 1 1 1 .

Jakub Szyguła 27.06.2024 15:31

@JakubSzyguła обратное не работает из-за проблем с плавающей запятой.

Mayukh Bhattacharya 27.06.2024 15:52

Я бы сначала отсортировал веса от большего к меньшему.

Для первых пяти используйте =ROUND($A$2*D2/SUM($D$2#),0), чтобы округлить до ближайшего целого числа.

Затем для последнего веса просто используйте =A2-SUM(E2:E6), чтобы сумма всегда была 786.

Не математически строго, но я думаю, что в большинстве случаев это должно работать.

Рассмотрим веса «10, 10, 10, 10, 10, 4». Первые 5 записей равны (без округления) 145,5556, которые вы округляете до 146, но шестая запись равна (без округления) 58,222, но вы выводите 56…

Chronocidal 02.07.2024 15:02

@Chronocidal Да, твоя версия намного лучше.

rachel 02.07.2024 15:11

Если у вас MS365, то эта LAMBDA формула даст желаемые результаты.

=LET(tgt,F2,weights,G2:G7,fx,tgt/SUM(weights),sub,REDUCE(0,DROP(weights,1),LAMBDA(a,c,a+ROUND(fx*c,0))),BYROW(weights,LAMBDA(r,IF(ROW(r)=ROW(tgt),tgt-sub,ROUND(fx*r,0)))))

Если выполняются оба следующих условия:

  • число меньше суммы весов
  • есть веса незначительной величины

тогда функция может выдать распределение с нулевым или отрицательным значением (хотя технически это все равно будут целые числа).

(если, как я подозреваю, это своего рода упражнение по распределению финансов, то и то, и другое никогда не будет правдой)

Ответ принят как подходящий

Хорошо, это может быть немного сложно, но:

=LET(total,$A$2,weights,$B$2:$B$7,valTbl,MAKEARRAY(COUNTA(weights),2,LAMBDA(y,x,IF(x=1,y,total*INDEX(weights,y)/SUM(weights)))),sortTbl,SORTBY(valTbl,MOD(INDEX(valTbl,,2),1),-1),lowtotal,SUM(ROUNDDOWN(INDEX(valTbl,,2),0)),outTbl,MAKEARRAY(COUNTA(weights),2,LAMBDA(y,x,ROUNDDOWN(INDEX(sortTbl,y,x),0)+IF(AND(x=2,y<=(total-lowtotal)),1,0))),INDEX(SORT(outTbl,1,1),,2))

(Из-за использования функций LAMBDA и MAKEARRAY это не будет работать в более старой версии Excel)

Как это работает:

Сначала он создает массив valTbl, который содержит номер строки и точное пропорциональное значение (включая десятичные дроби).

Ряд Ценить 1 134,359 2 87.33333 3 80,61538 4 53,74359 5 26.87179 6 403.0769

Затем он сортирует это значение по убыванию по десятичной части значения в sortTbl:

Ряд Ценить 5 26.87179 4 53,74359 3 80,61538 1 134,359 2 87.33333 6 403.0769

Он суммирует целые части значений (783), вычитает это из общей суммы (786-783 = 3), которую мы временно будем называть 𝕐, затем создает новый outTbl, беря целые части значений и добавляя 1 до первых 𝕐 записей:

Ряд Ценить 5 27 (+1) 4 54 (+1) 3 81 (+1) 1 134 (+0) 2 87 (+0) 6 403 (+0)

Наконец, мы сортируем это по возрастанию по строке (что возвращает исходный порядок) и выводим только столбец «Значение»:

Результат 134 87 81 54 27 403

Благодаря тому, как это работает, это работает даже в таких случаях, когда наши веса приводят к совпадению десятичных частей: (при этом приоритет отдается более ранним строкам, но вы можете расширить SortBy, чтобы изменить это, если вы хотите установить приоритет больших или меньших целочисленных значений или чего-то еще). )

Число Масса → Строка¹ Значение¹ → Ряд² Значение² → Строка³ Значение³ → Результат 100 3 → 1 33.3333 → 1 33.3333 → 1 34 (+1) → 34 3 → 2 33.3333 → 2 33.3333 → 2 33 (+0) → 33 3 → 3 33.3333 → 3 33.3333 → 3 33 (+0) → 33

или даже

Число Масса → Строка¹ Значение¹ → Строка² Значение² → Строка³ Значение³ → Результат 100 1 → 1 8.3333 → 1 8.3333 → 1 9 (+1) → 9 4 → 2 33.3333 → 2 33.3333 → 2 33 (+0) → 33 7 → 3 58.3333 → 3 58.3333 → 3 58 (+0) → 58

Отличный ответ. Скорее всего, я не буду работать со старой версией Excel, которая есть у меня дома, но она содержит ответ в одной формуле. (Я использовал ту же методологию, но мне пришлось хранить промежуточные результаты в ячейках, а не в массивах.)

Jakub Szyguła 04.07.2024 15:38

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