Битовые операции

23.07.14

Разработка - Универсальные функции

Пример того, как можно вызывать битовые операции из 1С
Занимаясь программой для поиска решений головоломки Bedlam Cube, я задался вопросом, а можно ли в 1С реализовать битовые операции. Дело в том, что кубик, который надо собрать, имеет размеры 4х4х4. А значит его можно описать с помощью 64-х разрядного числа, в котором каждый бит соответствует ячейке (клетке) головоломки. В 1С числа представляются в виде строк и , как следствие, операций над битами нет. Но побитовые операции есть в Transaq-SQL (& - побитовое И, | - побитовое ИЛИ, ^ -  побитовое исключающее ИЛИ). Среди типов данных, которые входят в стандарт языка Transaq-SQL присутствует bigint, которое имеет длину 8 байт, что и соответствует 64-х разрядному числу. Сначала я создал хранимые процедуры, с помощью которых выполняются побитовые операции. Ниже приведен пример одной из них.

CREATE PROCEDURE [dbo].[BitOR]

-- Add the parameters for the stored procedure here
@BigInt1 bigint,
@BigInt2 bigint
AS
BEGIN
 SET NOCOUNT ON;
 SELECT @BigInt1 | @BigInt2
END

Аналогично можно реализовать две оставшиеся операции. Теперь покажем как организовать вызов данных процедур из 1С. Для этого нам потребуется подключение к SQL серверу.
Функция глSQLПодключение() Экспорт
SQLConnect = Новый COMОбъект("ADODB.Connection"); 
ConnectionString = "driver={SQL Server}; server=<Имя сервера>; uid=<Имя пользователя>; pwd=*******; DataBase=<Имя базы> ";
SQLConnect.ConnectionTimeOut =600;SQLConnect.CursorLocation = 3;
попытка
SQLConnect.Open(ConnectionString);
исключение
SQLConnect="";
Предупреждение("Невозможно установить соединение");
возврат Неопределено;
конецпопытки;
возврат SQLConnect;
КонецФункции
Приведенная функция в случае успешного завершения возвращает com-объект, который позволяет выполнять команды на SQL сервере. Используя созданное подключение, мы можем вызвать хранимую процедуру. Ниже пример того, как это сделать из 1С.
Функция BitOr(вхЧсл1,вхЧсл2,вхSQLConnect)
CmdSQL = Новый COMОбъект("ADODB.Command")    ;
CmdSQL.ActiveConnection = вхSQLConnect       ;   
CmdSQL.CommandText = "EXEC [dbo].[BitOr] "+Формат(вхЧсл1,"ЧН=0; ЧГ=0")+","+Формат(вхЧсл2,"ЧН=0; ЧГ=0");
rs=CmdSQL.Execute();
rs.MoveFirst();
возврат rs.Fields(0).Value;
КонецФункции
Теперь поговорим о том, как получить текущее состояние кубика. В 1С реализованы длинное умножение и сложение, а длина данных, с которыми можно оперировать, определяется исключительно размером доступной памяти. Поэтому получить массив, в котором хранятся значения степеней двойки для значений показателя от 0 до 63, труда не составляет. Далее каждой  точке с координатами x,y и z  мы можем сопоставить число из диапазона 0...63. Это число рассчитывается по формуле z+4*(y+4*x). После этого, чтобы получить состояние,описывающее наш кубик, мы должны для каждой заполненной точки вычислить ее положение в одномерном массиве, найти значение двойки в данной степени и полученные числа сложить. Все просто и понятно. Но тип данных bigint хранит данные в диапазоне (-2^63) до (2^63-1), а значит при попытке передать в хранимую процедуру число 2^63 мы получим ошибку. Нам надо понять какому значению соответствует двоичная запись, которая содержит 0 во всех разрядах, кроме самого старшего. Для этого надо найти информацию о представлении в памяти целых отрицательных чисел. Это не сложно. Алгоритм следующий, надо взять двоичную запись положительного числа, инвертировать ее, то есть 0 заменить на 1, а 1 на 0, затем к получившемуся числу прибавить 1. Используя полученные сведения, найдем представление для (-1):
  1. Двоичная запись 1 - 0x000...001
  2. Инвертируем 0x111...110
  3. Прибавляем 1, получаем 0x111...111
Вспоминаем, что двоичная запись для (2^63 -1) это 0x011...111 ( единица во всех разрядах кроме старшего). Ну и последний шаг, вычтем из двоичного представления для (-1) двоичное представление для (2^63 -1), получим 0x100...000. Таким образом, когда нам надо заполнить самый старший бит в двоичном представлении нашего куба, мы должны к числу, описывающему текущее состояние, прибавить (-2^63). Что я и сделал. И это все заработало !
Поиск решения заключается в переборе всех возможных вариантов исходных элементов. Для этого я предварительно подготовил таблицу состояний, в которой  для каждой фигуры и каждого  положения фигуры вычислил ее характеристику, как это описано выше. Затем в процедуре поиска, когда мне нужно было проверить можно ли разместить фигуру в кубике, я вычислял логическое И между текущим состоянием и характеристикой фигуры и если оно равнялось нулю, то фигуру можно было разместить. Поставить фигуру - вычислить логическое ИЛИ между текущим состоянием и характеристикой фигуры, снять фигуру - вычислить логическое ИСКЛЮЧАЮЩЕЕ ИЛИ  между текущим состоянием и характеристикой фигуры. Разумеется, изложенную методику я реализовал, как дополнительную к более простой, когда состояние кубика описывалось трехмерным массивом.
Ну и ответ на вопрос, зачем это надо. Человеческий мозг содержит около 86 млрд. нейронов, но не это количество делает его поистине уникальным. Значительно важнее связи между нейронами, а вот здесь количество сочетаний становится просто астрономическим. Возможно, прочитав эту статью, у вас сложится неожиданная цепочка, которая впоследствии приведет к решению задачи, весьма далекой от изложенной. 




битовые операции TRANSAQ-SQL

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2664    0    John_d    8    

53

GUID в 1С 8.3 - как с ними быть

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    4595    atdonya    22    

45

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    3956    ke.92@mail.ru    16    

61

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    8802    YA_418728146    6    

141

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2071    21    progmaster    7    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16140    133    sapervodichka    112    

129

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7242    quazare    8    

109
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. viollan 30.07.14 11:47 Сейчас в теме
Прошу прощения, но заголовок статьи не соответствует содержанию. Вы выполняете побитовые операции не на 1С, а на SQL. С таким успехом можно выполнить эти действия используя .Net, ВК и пр.
2. scientes 288 30.07.14 12:36 Сейчас в теме
Благодарю за замечание, внес исправления в анонс статьи.
3. kg_am 173 01.08.14 12:42 Сейчас в теме
Что-то мне подсказывает, что вызов CmdSQL.Execute() будет происходить по-любому на порядок дольше, чем если средствами языка 1С перевести числа в двоичную систему и сделать всё, что нужно.
4. scientes 288 04.08.14 14:21 Сейчас в теме
Вы правы, решение с обращением к SQL серверу увеличивает время расчета, и чем больше перебирается вариантов, тем больше это различие. Я и не говорю, что предложенный способ лучше. Он рабочий, это верно.
5. kg_am 173 05.08.14 20:07 Сейчас в теме
У меня получилась такая функция побитового "или":

Функция BitOr(вхЧсл1, вхЧсл2)
	ОстатокЧ1 = вхЧсл1;
	ОстатокЧ2 = вхЧсл2;
	Множитель = 1;
	Результат = 0;
	Пока ОстатокЧ1 <> 0 и ОстатокЧ2 <> 0 Цикл
		Результат = Результат + Макс(ОстатокЧ1 % 2, ОстатокЧ2 % 2) * Множитель;
		ОстатокЧ1 = Цел(ОстатокЧ1 / 2);
		ОстатокЧ2 = Цел(ОстатокЧ2 / 2);
		Множитель = Множитель * 2;
	КонецЦикла;
	Возврат Результат + (ОстатокЧ1 + ОстатокЧ2) * Множитель;
КонецФункции
Показать


Дёшево и сердито. Главное - быстро.
Оставьте свое сообщение