Проблемы с Uint64

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Проблемы с Uint64

Сообщение CRobin » 15.08.2016 16:15:55

Здравствуйте. Надавно стал замечать, что в ранее работавшем коде стали появляться логические ошибки. После дебага оказалось что ошибка возникает в результат выполнения арифметических операций с двумя переменными типа Uint64. Например 110840 - 110842 = 18446744073709551614. Как я понимаю вычитание беззнаковых интерпретирует результат вычитание как такое же беззнаковое число. Но ранее этого небыло. Что я мог сломать и откуда взялась такая странная логика? Lazarus 1.4.4 оптимизация O3
CRobin
постоялец
 
Сообщения: 145
Зарегистрирован: 26.01.2016 12:15:39

Re: Проблемы с Uint64

Сообщение Лекс Айрин » 15.08.2016 16:27:50

А если отключить оптимизацию?

Добавлено спустя 4 минуты 56 секунд:
Вообще, результат законен. При вычитании большего из меньшего и должно получиться такое громадное число, если не используется информация о переполнении регистра. Есть подозрение, что излишне ретивый оптимизатор эту проверку убирает, считая, что за этим должен следить программист.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Проблемы с Uint64

Сообщение Дож » 15.08.2016 16:32:57

Например 110840 - 110842 = 18446744073709551614.

А что, по-вашему, должно являться результатом вычитания этих чисел в UInt64?
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Проблемы с Uint64

Сообщение CRobin » 15.08.2016 16:37:40

Дож писал(а):А что, по-вашему, должно являться результатом вычитания этих чисел в UInt64?

должно получится -2 и ранее получалось
CRobin
постоялец
 
Сообщения: 145
Зарегистрирован: 26.01.2016 12:15:39

Re: Проблемы с Uint64

Сообщение Лекс Айрин » 15.08.2016 16:40:26

CRobin, вообще-то, это было из-за того, что переменные неявно превращались в знаковые, а потом, если надо, обратно.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Проблемы с Uint64

Сообщение CRobin » 15.08.2016 16:44:42

Лекс Айрин писал(а):CRobin, вообще-то, это было из-за того, что переменные неявно превращались в знаковые, а потом, если надо, обратно.

Я ничего не менял в коде. Могу только вспомнить восстановление LPI и LPS файлов после падения диска, может быть там были объявлены какие то опции компилятора?
CRobin
постоялец
 
Сообщения: 145
Зарегистрирован: 26.01.2016 12:15:39

Re: Проблемы с Uint64

Сообщение Лекс Айрин » 15.08.2016 16:50:12

CRobin, ты нет. А вот компилятор (оптимизатор) вполне.
по ссылке пример для языка С++, но, на самом деле, проблема может возникнуть для любого языка.
https://habrahabr.ru/post/307702/

Ах, да... именно во избежание подобных бяк и не люблю использовать беззнаковые типы, хотя иногда и можно было бы.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Проблемы с Uint64

Сообщение Дож » 15.08.2016 17:52:26

CRobin писал(а):
Дож писал(а):А что, по-вашему, должно являться результатом вычитания этих чисел в UInt64?

должно получится -2 и ранее получалось

UInt64 расшифровывается как Unsigned (беззнаковый) Integer на 64 бита. Как и полагается беззнаковому типу, он не может хранить отрицательные числа
Код: Выделить всё
begin
  Writeln('UInt64 of -2 = ', UInt64(-2));
end.

Код: Выделить всё
UInt64 of -2 = 18446744073709551614


Т.е. сейчас указанная вами проблема про вычитание не является ошибкой, а если ранее вы наблюдали -2 в UInt64, то это было что-то странное.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Проблемы с Uint64

Сообщение Лекс Айрин » 15.08.2016 18:04:37

Дож писал(а): то это было что-то странное.


всего лишь приведение типа, ничего странного. Не думаю, что он присваивал результат в беззнаковую переменную. Другое дело, что этоо детали реализации, которые не всегда явно прописаны.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Проблемы с Uint64

Сообщение Дож » 15.08.2016 18:07:49

Лекс Айрин и где это приведение типов? Я что-то не вижу никакого кода.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Проблемы с Uint64

Сообщение CRobin » 15.08.2016 18:35:03

Дож писал(а):сейчас указанная вами проблема про вычитание не является ошибкой, а если ранее вы наблюдали -2 в UInt64, то это было что-то странное.


Паскаль допускает относительно свободное обращение с типами, например складывать и челочисленные и дробные типы. В моем случае операция вычитания беззнаковых типов применялась в условии
Код: Выделить всё
if a - b > c then
изза этого возникала ошибка самого алгоритма. Решил проблему явным указанием типа
Код: Выделить всё
if int64(a - b) > c then
. Вообще говоря, меня пугает не то что надо приводить тип, а непредсказукемость алгоритма, поскольку ранее поведение этих проверок было другое.
CRobin
постоялец
 
Сообщения: 145
Зарегистрирован: 26.01.2016 12:15:39

Re: Проблемы с Uint64

Сообщение Лекс Айрин » 15.08.2016 20:50:51

Дож, в паскале много неявного приведения, которое в код добавляет компилятор.

CRobin, всякое бывает. Иногда и не знаешь где аукнется.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Проблемы с Uint64

Сообщение alexey38 » 17.08.2016 09:46:03

Вообще-то операция "if a - b > c then" с беззнаковыми типами, если "b" больше "a" является грубой логической ошибкой программиста, а не компилятора. Раньше, когда по молодости делал такие же ошибки в Borland Pascal или Delphi, то при выполнении программа вылетала с ошибкой типа, по-моему, "Run time Error 201 ...".

Когда начал работать в области промышленной автоматизации, то за такие косяки могли уволить с работы или лишить премии на полгода вперед. А если кто-то пытался оправдаться, говоря, что при отключенных проверках диапазонов программа работает правильно, то увольняли сразу и без дальнейших разговоров.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

Re: Проблемы с Uint64

Сообщение zub » 17.08.2016 12:27:05

alexey38
Давайие сразу сажать за такое))
Обычная ошибка, не лучше не хуже других.

Мерилом в подобных случаях у разрабов является делфи. Раньше было както посвоему, теперь стало как в делфи.
Сейчас (в транке fpc) например такой код работает поразному в делфи\фпц
Код: Выделить всё
program Project1;

{$APPTYPE CONSOLE}

var
  a,b:longword;
begin
  a:=1;b:=2;
  if (a-b)>0 then
   Writeln('Passed');
  readln;
end.

Напишет ктонить багрепорт и CRobin еще раз удивится))
>>Вообще говоря, меня пугает не то что надо приводить тип, а непредсказукемость алгоритма
Алгоритм тут совершенно непричем,
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Проблемы с Uint64

Сообщение alexey38 » 17.08.2016 12:51:19

zub писал(а):alexey38Давайие сразу сажать за такое)). Обычная ошибка, не лучше не хуже других.
...
>>Вообще говоря, меня пугает не то что надо приводить тип, а непредсказукемость алгоритма
Алгоритм тут совершенно непричем,


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

В лучшем случае ошибки приводят к дополнительным командировкам, как на разбор сбоя, так и на последующее устранение с переналадкой и испытаниями. Убыток от такой ошибки может легко составить, например, 200 т.р. (на обозначенные дополнительные расходы, если объект удаленный).

Поэтому в промышленной автоматизации очень строго с ошибками, особенно с такими, которые трудно выявляются при тестировании.

Поэтому алгоритм программы должен быть составлен таким образом, чтобы были полностью исключены неопределенности компиляторов и т.п.
alexey38
долгожитель
 
Сообщения: 1627
Зарегистрирован: 27.04.2011 19:42:31

След.

Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 8

Рейтинг@Mail.ru