Имя: Пароль:
1C
 
Агенты из нуль-пространства пытаются испортить коллайдер на 1С (задача)
🠗 (Волшебник 20.05.2025 16:15)
0 Волшебник
 
19.05.25
16:06
В компьютере Большого адронного коллайдера наконец-то начала применяться 1С 8.3.27.
В нём есть контрольная функция, текст которой представлен ниже.

Казалось бы, программист 1С всё предусмотрел, включая вмешательство агентов из нуль-пространства.
Для справки: агенты нуль-пространства могут вставлять и удалять любое количество нулей в строки внутри кавычек.

Тем не менее, коллайдер сломался и никакие предварительные проверки не сработали, т.е. не было сообщения, а продакшен упал с окошком:




Вопрос: какое было вмешательство агентов из нуль-пространства? Какую проверку надо добавить, чтобы пресечь подобное вмешательство в будущем?

Функция ВычислительРаботаетКорректно()
	
	А = "1.0"; 
	Б = "0.1";
	
	Если СтрДлина(А) <> СтрДлина(Б)
		ИЛИ Число(А) <> Вычислить(А)
		ИЛИ Число(Б) <> Вычислить(Б) Тогда
		
		Сообщить("Обнаружено потустороннее вмешательство из нуль-пространства!");
		Возврат Ложь;
	КонецЕсли; 	
	
	КонтрольноеВыражение1 = А + "+" + Б; // А+Б
	КонтрольноеВыражение2 = Б + "+" + А; // Б+А
		
	// так как от перестановки слагаемых сумма не меняется, то их равенство означает корректность вычислений 
   	Возврат Вычислить(КонтрольноеВыражение1) = Вычислить(КонтрольноеВыражение2); 
КонецФункции
1 Fish
 
гуру
19.05.25
16:12
Проверить КонрольноеВыражение1 И КонрольноеВыражение2 на длину, т.к. скорее всего именно туда были нули вставлены.
2 Волшебник
 
19.05.25
16:14
(1) Уже есть проверка на совпадение их длины.
3 Fish
 
гуру
19.05.25
16:24
(2) Я имел в виду проверить на длину 3. Если больше - то было вмешательство.
4 Fish
 
гуру
19.05.25
16:17
(2) Не совпадение длины, а
Если СтрДлина(КонтрольноеВыражение1) <> 3 ИЛИ СтрДлина(КонтрольноеВыражение2) <> 3 Тогда

Вмешательство.

КонецЕсли
5 Волшебник
 
19.05.25
16:27
(3) Всё равно не поможет. Агенты нуль-пространства, сука, хитрые...
6 Eiffil123
 
19.05.25
16:28
в порядке бреда - в одну из строк навставлять нулей, чтоб при преобразовании к дате пыталось кастануться и валилось с ошибкой.
7 Волшебник
 
19.05.25
16:30
(6) Какой-то бред... При чём тут даты?
8 Fish
 
гуру
19.05.25
16:34
(5) Почему не поможет? Очень даже поможет. Если следовать условию, то они могут только добавлять или удалять нули внутри кавычек.

Значит, в выражении А + "+" + Б они могут только добавить нули внутри кавычек: "+". А удалить они ничего не могут, т.к. в этой строке нулей нет.

Поэтому проверка на длину = 3 сработает.
9 Eiffil123
 
19.05.25
16:35
(8) так надо понять сначала что сломали, потом уже проверки креативить
10 Волшебник
 
19.05.25
16:36
(8) Зря так думаете.
11 Fish
 
гуру
19.05.25
16:36
(9) Я в (1) написал, что сломали.
12 Волшебник
 
19.05.25
16:36
(11) Сломали первые 2 строки:
А = "1.0"; 
Б = "0.1";
13 Fish
 
гуру
19.05.25
16:37
(10) Значит, условие некорректное.
14 Волшебник
 
19.05.25
16:38
(13) Условие корректное. Это просто программист 1С слабоват.
15 Eiffil123
 
19.05.25
16:42
(11) добавление нулей в (1) не приводит к краху платформы, как этого требует условие.
16 Волшебник
 
19.05.25
16:43
(13) Давайте Вашу функцию, а я испорчу её как агент нуль-пространства.
17 Eiffil123
 
19.05.25
16:46
вот если нолики снести, то код портится:

(хз как тут картинки в сообщения вставляются)
18 Fish
 
гуру
19.05.25
16:46
(16) Например, такое вмешательство даёт ошибку, но другую:

А = "1.";
Б = ".1";
19 Fish
 
гуру
19.05.25
16:48
+(18) Ну а проверку надо добавить на преобразование А и Б в число, и потом, что сумма = 1.1. Тогда не было вмешательства
20 Волшебник
 
19.05.25
16:49
(17)(18) Ну и что будем делать, товарищи-программисты?
21 Волшебник
 
19.05.25
16:50
(19) Костыльно.
22 Eiffil123
 
19.05.25
16:54
(20) с вас 5тыщ

Функция ВычислительРаботаетКорректно()
	
	А = "1.0"; 
	Б = "0.1";
	
	Если СтрДлина(А) <> СтрДлина(Б)
		ИЛИ Число(А) <> Вычислить(А)
		ИЛИ Число(Б) <> Вычислить(Б) Тогда
		
		Сообщить("Обнаружено потустороннее вмешательство из нуль-пространства!");
		Возврат Ложь;
	КонецЕсли; 	
	
	КонтрольноеВыражение1 = А + "+" + Б; // А+Б
	КонтрольноеВыражение2 = Б + "+" + А; // Б+А
		
	// так как от перестановки слагаемых сумма не меняется, то их равенство означает корректность вычислений 
	Попытка
   	Возврат Вычислить(КонтрольноеВыражение1) = Вычислить(КонтрольноеВыражение2); 
	Исключение
		Возврат Ложь; // ИДЕАЛЬНО
	КонецПопытки;
	
КонецФункции
23 Волшебник
 
19.05.25
16:55
(22) 👍 Почти решение. Для красоты испортите и верните длину А и Б, чтобы было по 3 символа, а то длина программы изменилась (палево для агентов)
24 Гена
 
гуру
19.05.25
16:56
(22) А можно проверить:
А = "10.0";
Б = "0.01";
?
25 Волшебник
 
19.05.25
16:56
(24) Гена, у Вас нуль-агенты табло украли?
26 Гена
 
гуру
19.05.25
16:58
(25) Ещё не изучил )
27 Волшебник
 
19.05.25
17:00
(26) Программа отработала с результатом "Истина", как будто вмешательства не было.
Значит вмешательство возможно.
Другое вмешательство поломало коллайдер.
28 Гена
 
гуру
19.05.25
17:12
(27) В том-то и грусть, что пойдут на коллайдер ДРУГИЕ параметры, он отработает, пойдёт в разнос и пипец.
А надо дать на вход именно что 1.0 и 0.1
29 Волшебник
 
19.05.25
17:14
(28) Агенты нуль-пространства меняют входные параметры А и Б. Функция должна выдать сообщение, если произошло некорректное вмешательство. Если вмешательство арифметически корректное, то нехай работать с их вмешательством.
30 Гена
 
гуру
19.05.25
17:15
(29) Мне так не нравится. В Чернобыле тоже задали другие начальные параметры.
31 Волшебник
 
19.05.25
17:17
(30) Тут важно проверить корректность работы вычислителя. Если он корректно работает даже после вмешательства, то и отлично. Но важно устранить вмешательство, которое ломает вычислитель.
32 Fish
 
гуру
19.05.25
17:19
(31) Ну если вмешательство не приводящее к ошибке пофиг, тогда надо проверить, что А и Б не начинаются с точки, т.к. только это даёт ошибку.
33 Волшебник
 
19.05.25
17:34
(32) А ведь это очень странно...

Выражение "1.0+.1" в табло выдаёт 1.1

Вычислить("1.0+.1") тоже возвращает 1.1
34 Dmitrii
 
гуру
19.05.25
17:46
Должно работать при условии, что вмешательства агенты могут произвести только в А и Б, и нигде больше.

Если НЕ (XMLСтрока("1.0") = XMLЗначение(Тип("Строка"), А)
  И XMLСтрока("0.1") = XMLЗначение(Тип("Строка"), Б))
    Сообщить("Обнаружено потустороннее вмешательство из нуль-пространства!");
    Возврат Ложь;
КонецЕсли;
35 Волшебник
 
19.05.25
20:21
Я говорил про это:


В 1С от перестановки слагаемых иногда меняется сумма.
Похоже, это связано с литералами и преобразованиями типов.
Синтаксический анализатор выражения разбивает его на лексемы и иногда сразу входит в числовой контекст, что ему помогает анализировать следующие литералы, а иногда не может понять тип первого литерала в контексте выражения и выдаёт ошибку. При этом отдельно этот литерал он распознаёт как число.
36 Волшебник
 
19.05.25
20:41
(32) 👍 Похоже, это единственное костыльное решение задачи. Хотя даже скобки не помогают. Задачу можно было бы усложнить и для скобок, но другого я не вижу.
37 Волшебник
 
19.05.25
22:04
Агенты из нуль-пространства — это математики, которые позволяют добавлять/удалять ведущие/конечные нули в любом количестве. Вредят программистам.
38 Олдж
 
naïve
19.05.25
21:50
Функция ВычислительРаботаетКорректно()
    
    А = "1.0";
    Б = "0.1";
    
    Если СтрДлина(А) <> СтрДлина(Б)
        ИЛИ Число(А) <> Вычислить(А)
        ИЛИ Число(Б) <> Вычислить(Б) Тогда
        
        Сообщить("Обнаружено потустороннее вмешательство из нуль-пространства!");
        Возврат Ложь;
    КонецЕсли;     
    
    КонтрольноеВыражение1 = ЧИСЛО(А) + ЧИСЛО(Б); // А+Б
    КонтрольноеВыражение2 = ЧИСЛО(Б) + ЧИСЛО(А); // Б+А
    // так как от перестановки слагаемых сумма не меняется, то их равенство означает корректность вычислений
    Возврат КонтрольноеВыражение1 = КонтрольноеВыражение2;
    
КонецФункции
39 Волшебник
 
19.05.25
21:54
(38) Не сработает при А="1.0" и Б=".10"
Агенты вмешались, а вычислитель (функция Вычислить) работает некорректно.
40 Волшебник
 
19.05.25
21:56
Разгадка в том, что функция Вычислить() производит разбор лексем и приведение типов. От перестановки ЛЕКСЕМ их сумма после приведения типов может измениться.
41 Волшебник
 
19.05.25
23:28
Резюме: Баг в платформе 1С:
Функция Вычислить() работает некорректно при перестановке числовых слагаемых.
42 1СинийКит
 
20.05.25
14:59
Функция ВычислительРаботаетКорректно()
    
    А = "1.";
    Б = ".1";
    
    Если СтрДлина(А) <> СтрДлина(Б)
        ИЛИ Число(А) <> Вычислить(А)
        ИЛИ Число(Б) <> Вычислить(Б) Тогда
        
        Сообщить("Обнаружено потустороннее вмешательство из нуль-пространства!");
        Возврат Ложь;
    КонецЕсли;     
    
    КонтрольноеВыражение1 = Вычислить(А) + Вычислить(Б); // А+Б
    КонтрольноеВыражение2 = Вычислить(Б) + Вычислить(А); // Б+А
        
    // так как от перестановки слагаемых сумма не меняется, то их равенство означает корректность вычислений
       Возврат КонтрольноеВыражение1 = КонтрольноеВыражение2;  
    
КонецФункции

ps:
Если СтрДлина(А) <> СтрДлина(Б)
        ИЛИ Число(А) <> Вычислить(А)
        ИЛИ Число(Б) <> Вычислить(Б)
        Лев(Б,1) = "." Тогда
43 Волшебник
 
20.05.25
15:02
(42) пропущено ИЛИ, не проверяется А
44 1СинийКит
 
20.05.25
15:15
(43) а зачем проверять А?
45 Волшебник
 
20.05.25
18:01
(44) хм... С этим согласен
46 Dmitrii
 
гуру
20.05.25
18:35
И чем вам решение из (32) не угодило?
Работает на том же принципе - контроль корректности преобразования типов, сделанных разными методами.
Проблема начала числа с точки была очевидна с самого начала. Если ограничиваться только ею, то костыля с проверкой Лев(Б, 1) = "." вполне достаточно.

PS Ненавижу такие задачи.
С одной стороны иногда помогают нестандартно посмотреть на какие-то обычные вещи и обратить внимание на какое-то особенности или нюансы. Но с другой стороны - никогда не понимаешь чего именно хотел автор задачи - толи универсального решения, толи тупого решения "в лоб".
47 Волшебник
 
20.05.25
22:41
(46) Ну простите. Я заметил баг в платформе 1С, не смог пройти мимо. Высосал задачу из пальца
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.