Применить поразрядную функцию Excel (BITAND или BITOR) к диапазону с большими значениями

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

Я могу использовать следующую функцию VBA, которую я написал для неотрицательных значений Long до 2 31, но она переполнится для чего-то большего.

Function RangeBitOr(rng As Range) As Long
Dim i As Long
Dim cell As Range

i = 0
For Each cell In rng
    i = i Or CLng(cell.Value)
Next cell

RangeBitOr = i

End Function

Встроенные функции Excel BITAND и BITOR (представленные в Excel 2013) могут обрабатывать значения вплоть до 2 48 - 1, и я бы хотел, чтобы эта возможность была применена к диапазону.

Есть ли простой способ заставить эти битовые операторы работать в диапазоне до этого предела?

Я пробовал пару обходных путей:

  1. Создание двух новых столбцов и использование MOD для разделения больших значений на два меньших, затем использование моей функции RangeBitOr для каждого из них, а затем повторное объединение значений.

  2. Создание столбца для функции BITOR для объединения текущего агрегата с текущим значением и принятие последнего в качестве общего BITOR для диапазона.

В идеале я хотел бы иметь решение, которое не требует вспомогательных столбцов или VBA, но я открыт для любых полезных предложений.


person Alexis Olson    schedule 04.08.2016    source источник
comment
Вы используете 32-битную или 64-битную версию Excel?   -  person Comintern    schedule 05.08.2016
comment
У него нет удобной 64-битной установки, но поместите значение 9223372036854770000 в ячейку A1 и посмотрите, что вернет Debug.Print TypeName(Range("A1").Value).   -  person Comintern    schedule 05.08.2016
comment
Если я это сделаю, это будет дубль.   -  person Alexis Olson    schedule 05.08.2016
comment
Хорошо, это то же самое, что и 32 бит. Вы должны иметь возможность использовать Тип данных LongLong вместо Long. Я бы попробовал - просто заменил все Long на LongLong, а приведение CLng() к CLngLng().   -  person Comintern    schedule 05.08.2016
comment
Я бы протестировал это - поскольку Excel маршалирует до Double, может быть потеря точности приведения, если входное значение больше 9,007,199,254,740,992.   -  person Comintern    schedule 05.08.2016
comment
Потрясающие! Он работает по крайней мере до этого предела (и мне не нужно ничего большего).   -  person Alexis Olson    schedule 05.08.2016
comment
Идите вперед и опубликуйте это как самостоятельный ответ - как я уже сказал, у меня нет возможности проверить это (и в любом случае у меня есть репутация в течение дня).   -  person Comintern    schedule 05.08.2016


Ответы (2)


Как отмечает @Comintern в комментариях, моя функция VBA может быть расширена как минимум до BITOR предела 2 48 - 1 (возможно, до 9,007,199,254,740,992 = 2 53 или выше), просто заменив Long на LongLong следующим образом:

Function RangeBitOr(rng As Range) As LongLong
Dim i As LongLong
Dim cell As Range

i = 0
For Each cell In rng
    i = i Or CLngLng(cell.Value)
Next cell

RangeBitOr = i

End Function

Если у кого-то есть решение, отличное от VBA, мне все еще интересно.

person Alexis Olson    schedule 05.08.2016

Я не думаю, что есть какие-либо чистые формулы, если MS не решит расширить функцию, включив диапазоны

Но если вы хотите, вы все равно можете вручную использовать формулу обходного пути, например

=BITOR(A1, BITOR(B1, BITOR(C1, BITOR(D1))))

Тот же метод можно использовать для BITAND


Если вы можете потратить немного места, чтобы уменьшить объем ручного набора текста, вы можете

  • Введите =BITOR(value1, value2) в первую ячейку
  • Перетащите его горизонтально n - 2 раз и вертикально столько же раз, чтобы получить список n значений.
  • Сделайте то же самое для оставшихся строк / столбцов, на одну ячейку меньше для каждой строки / столбца.

Результат такой же для 4 значений по ИЛИ, с окончательным результатом в ячейке D1.

A B C D
1 2 =BITOR(A1, A2) =BITOR(B1, B2) =BITOR(C1, C2)
2 4 =BITOR(A2, A3) =BITOR(B2, B3)
3 8 =BITOR(A3, A4)
4 16

Вы также можете использовать формулу массива для большого количества значений, чтобы уменьшить усилие перетаскивания, размер файла и повысить скорость

  • В первом столбце выберите 3 ячейки, введите =BITOR(A1:A3, A2:A4) и нажмите Ctrl + Shift + Enter
  • Щелкните маркер перетаскивания и перетащите столбец по горизонтали еще 2 раза. Результат будет аналогичным образом помещен в ячейку D1, как указано выше.
person phuclv    schedule 19.07.2018
comment
Вам не нужны все столбцы n-1. Вы можете просто ввести =BITOR(A(n), B(n-1)) в столбце B (кроме B1 = A1). - person Alexis Olson; 19.07.2018
comment
@AlexisOlson, но тогда вы больше не можете быстро перетащить формулу - person phuclv; 19.07.2018
comment
Не понимаю, почему бы и нет. Установите B1 = A1 и B2 = BITOR(A2, B1) и автозаполнение вниз. - person Alexis Olson; 19.07.2018