OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 22:43

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 68 ]  На страницу Пред.  1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 10:55 

Зарегистрирован: Пятница, 20 Июль, 2007 17:26
Сообщения: 710
Откуда: Псков
Придирка к :
"Еще один пример. У нас есть 10 тонн мусора. Сколько требуется вывезти трехтонных грузовиков, чтобы всё отправить на свалку?
10 DIV (-3) = -4"
собственно такая:
(-10) DIV (-3) = 4
один грузовик обеспечивает убыль в (-3), а нужно (-10)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 11:38 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
Иван Денисов писал(а):
Ну а деление на отрицательный делитель, ИМХО, всё таки имеет смысл в случае указания направления. Будь то направление движения денег, как в первом примере или направления поворота или движения чего-либо, как во втором.
Согласен, может.
И я думал над Вашими примерами, но в них присутствует произвольность в выборе знака. В том же примере с мусором Вы приписываете его количеству положительный знак, но если он вывозится, то есть вычитается, то должен быть отрицательным.

Я смог найти целостность условий задачи с результатами при отрицательном делителе только в случае оперирования отрицательными объектами. Если не прибегать к помощи антивселенной, то отрицательный объект можно интерпретировать как свободное место, которое тоже имеет физический смысл и может заканчиваться по тем же законам, что и объекты. Это может быть что угодно: и количество столиков(+) со свободными(-) от посетителей местами, и атомы(+) со свободными(-) от электронов орбиталями.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 13:17 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Про произвольность выбора знаков согласен, не всё чисто, подгонка получается.

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

В книге:
Nikitin E.W. Into the Realm of Oberon. New York, NY: Springer New York, 1997.
нашел вот тоже упоминание этой проблемы
Вложение:
div.png
div.png [ 88.53 КБ | Просмотров: 8432 ]


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 13:53 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
Хорошая ссылка, проясняющая позицию Вирта. Но я интепретировал неопределённость именно как ошибку времени исполнения или трансляции, потому что полагательство на платформоспецифическое поведение приводит к ошибкам на других платформах. Ошибкоустойчивый транслятор должен выявлять эту проблему, даже если на конкретной платформе это позволено и ожидаемо именно в таком виде.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 16:05 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
В задаче с грузовиками знаки вообще не нужны. Точно такой же смысл получится, если ждать, пока грузовик привезёт 10 тонн, везде плюсы будут. А для оператора DIV задача будет звучать "сколько полных грузовиков..." и для MOD будет задача "сколько тонн останется", а то что вы там огругляете в рамках деления в разные стороны - ничем реальным материальным не обосновано.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 17:50 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Пётр Кушнир писал(а):
В задаче с грузовиками знаки вообще не нужны. Точно такой же смысл получится, если ждать, пока грузовик привезёт 10 тонн, везде плюсы будут. А для оператора DIV задача будет звучать "сколько полных грузовиков..." и для MOD будет задача "сколько тонн останется", а то что вы там огругляете в рамках деления в разные стороны - ничем реальным материальным не обосновано.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 20:37 

Зарегистрирован: Пятница, 13 Март, 2015 16:40
Сообщения: 597
Иван Денисов писал(а):
Пётр Кушнир писал(а):
В задаче с грузовиками знаки вообще не нужны. Точно такой же смысл получится, если ждать, пока грузовик привезёт 10 тонн, везде плюсы будут. А для оператора DIV задача будет звучать "сколько полных грузовиков..." и для MOD будет задача "сколько тонн останется", а то что вы там огругляете в рамках деления в разные стороны - ничем реальным материальным не обосновано.

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

Но тогда уж поправьте: 10 DIV 3 всё ж таки 3, а то арифметикой за 4-й класс повеяло ;)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 21:20 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Artyemov писал(а):
а то арифметикой за 4-й класс повеяло ;)

Справедливости ради, надо заметить, что спор только про отрицательный числитель/знаменатель.

По честному будет ввести арифметический и экономический операторы, тогда все будут довольны. Я бы ещё упомянул то, что в обероне сдвиги арифметические, а логические только в модуле SYSTEM, тоже спорный момент


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 22:26 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Artyemov писал(а):
Иван Денисов писал(а):
Пётр Кушнир писал(а):
В задаче с грузовиками знаки вообще не нужны. Точно такой же смысл получится, если ждать, пока грузовик привезёт 10 тонн, везде плюсы будут. А для оператора DIV задача будет звучать "сколько полных грузовиков..." и для MOD будет задача "сколько тонн останется", а то что вы там огругляете в рамках деления в разные стороны - ничем реальным материальным не обосновано.

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

Но тогда уж поправьте: 10 DIV 3 всё ж таки 3, а то арифметикой за 4-й класс повеяло ;)

10 DIV (-3) = -4
Так в Обероне и в Компонентном Паскале, так что поправлять нечего. Компонентный Паскаль точно никто править не собирается ближайшее время :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 29 Июнь, 2018 23:22 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1428
В Обероне не так, на предыдущей странице было же.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Суббота, 30 Июнь, 2018 07:17 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Trurl писал(а):
В Обероне не так, на предыдущей странице было же.

Попытка проверить ваше утверждение в XDS привело к интересному наблюдению :)

Код:
<*+ MAIN *>
MODULE hello;

IMPORT InOut;
VAR res: INTEGER;
BEGIN
  res := 10 DIV (-3);
  InOut.WriteInt (res, 5);
  InOut.WriteLn;
END hello.


В XDS запрещен делитель меньше нуля при целочисленном делении.
shall not have a value less than 0

Код:
dia@lenovo:/usr/local/xds/samples/oberon$ xc hello.ob2
XDS Oberon-2 v2.40 [x86, v1.50] - build 03.02.2012
Compiling "hello.ob2"

* [hello.ob2 7.07 E029]
* incompatible types:
    "INT16"
    "whole constant (ZZ)"
  res $:= 10 DIV (-3);

* [hello.ob2 7.13 E107]
* shall not have a value less than 0
  res := 10 $DIV (-3);
errors  2, no warnings, lines   10, time  0.01


В Онлайн компиляторе действительно получается -3
https://models.molpit.org/model/134


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Суббота, 30 Июнь, 2018 07:43 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Проверил как во время исполнения обрабатывается ошибка.
Код:
<*+ MAIN *>
MODULE hello;

IMPORT InOut;
VAR a, b: INTEGER;
BEGIN
  a := -3;
  b := 10 DIV a;
  InOut.WriteInt (b, 5);  InOut.WriteLn;
END hello.


Он еще на этапе компиляции сказал, что ошибка во время исполнения будет, но разрешил собрать программу.
Код:
dia@lenovo:/usr/local/xds/samples/oberon$ xc =m hello.ob2
O2/M2 development system v2.60 TS  (c) 1991-2011 Excelsior, LLC. (build 03.02.2012)
XDS Oberon-2 v2.40 [x86, v1.50] - build 03.02.2012
Compiling "hello.ob2"

* [hello.ob2 8.11 W912]
* wholeDivException will be raised here
  b := 10 $DIV a;
no errors, warnings  1, lines   11, time  0.01
gcc  -o hello hello.o  /usr/local/xds/lib/x86/libts.a /usr/local/xds/lib/x86/libxds.a  -lm -lncurses -m32


Как компилятор предупреждал, сработала обработка исключения во время выполнения:
Код:
dia@lenovo:/usr/local/xds/samples/oberon$ ./hello

#RTS: unhandled exception #6: zero or negative divisor at line 8 of hello.ob2
#RTS: No history available.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Суббота, 30 Июнь, 2018 14:11 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
В OFront воплощение функции деления было сделано с ошибками. Они остаются в OFront+ и в voc
Код:
LONGINT SYSTEM_DIV(LONGINT x, LONGINT y) // INT64 SYSTEM_DIV(INT64 x, INT64 y)
{
  if (x == 0) return 0;
  if (x >= 0)
    if (y >= 0) {return x/y;}
    else        {return -((x-y-1)/(-y));}
  else
    if (y >= 0) {return -((y-x-1)/y);}
    else        {return (-x)/(-y);}
}

При условии ( (x < 0) # (y < 0) ) & ( ABS(x) > MAX(LONGINT) - ABS(y) ) будет переполнение несмотря на допустимые для деления входные параметры. Согласно стандарту Си переполнение целых чисел со знаком является неопределённым поведением, что не позволяет предсказать поведение программы для общего случая - возможна и аварийная остановка. При использовании флага компилятора -fwrapv в gcc и clang переполнение будет проводится в соответствии с машинными вычислениями в дополнительном коде. Но и тогда результат во многих случаях будет некорректным.
Также, из-за дополнительного кода будет выполняться некорректное равенство MIN(LONGINT) DIV (-1) = MIN(LONGINT) . clang для такого деления может сгенерировать аварийное завершение несмотря на флаг -fwrapv, что можно рассматривать как преимущество для диагностики.

В CPFront нет проблемы с переполнением
Код:
INTEGER SYSTEM_DIV(INTEGER x, INTEGER y)
{
   if (y > 0) {
      if (x < 0) return ~(~x / y);
      else return x / y;
   } else if (y < 0) {
      if (x > 0) return ~((x - 1) / -y);
      else return -x / -y;
   } else {
      __HALT(-5);
   }
}
Ещё одним преимуществом этого варианта в том, что в нём явная проверка деления на 0. В Си полагаться на то, что при делении на 0 произойдёт аварийная остановка в общем случае нельзя, потому что это тоже неопределённое поведение. Тем не менее, в решении для КП тоже есть проблема с делением минимального значения на -1, а трюки с побитовым отрицанием жёстко завязаны на дополнительный код.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Воскресенье, 01 Июль, 2018 22:28 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 520
Откуда: Украина, Днепропетровская обл.
Comdiv писал(а):
В OFront воплощение функции деления было сделано с ошибками. Они остаются в OFront+ и в voc
Comdiv писал(а):
в решении для КП тоже есть проблема с делением минимального значения на -1, а трюки с побитовым отрицанием жёстко завязаны на дополнительный код.
Предложите корректное решение, внесём правки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Воскресенье, 01 Июль, 2018 23:12 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
1. Побитовое отрицание эквивалентно вычитанию из -1.
2. Нельзя просто так менять знак отрицательного числа
2.1. Либо проверять на возможность переполнения при MIN(INTEGER)
2.2. Либо переписать так, чтобы отпала необходимость в смене знака
3. При отрицательных делимом и делителе нужно проверять на совпадение значений MIN(INTEGER) и -1


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Понедельник, 02 Июль, 2018 08:25 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1428
Иван Денисов писал(а):
Попытка проверить ваше утверждение в XDS привело к интересному наблюдению :)

Такого рода утверждения правильно проверять, читая описание языка.
Цитата:
The operators DIV and MOD apply to integer operands only. They are related by the following formulas defined for any dividend x and positive divisors y:
x = (x DIV y) * y + (x MOD y)
0 <= (x MOD y) < y


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Понедельник, 02 Июль, 2018 10:44 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Trurl писал(а):
Иван Денисов писал(а):
Попытка проверить ваше утверждение в XDS привело к интересному наблюдению :)

Такого рода утверждения правильно проверять, читая описание языка.
Цитата:
The operators DIV and MOD apply to integer operands only. They are related by the following formulas defined for any dividend x and positive divisors y:
x = (x DIV y) * y + (x MOD y)
0 <= (x MOD y) < y

Мне было интереснее проверить практически, как это реализовано. И тут к тому же написано, что только для положительного делителя определены эти формулы. Так что вопрос отрицательного делителя описанием языка не определен в этом фрагменте документации.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 12 Июль, 2019 01:35 

Зарегистрирован: Воскресенье, 03 Февраль, 2008 12:50
Сообщения: 249
Пётр Кушнир писал(а):
По честному будет ввести арифметический и экономический операторы, тогда все будут довольны.

Как в Аде, да. Две операции: rem (remainder) и mod (modulus). Первая определена согласно правилу A = (A/B)*B + (A rem B), вторая - A = B*N + (A mod B) для некоторого N. Иначе говоря, rem сохраняет знак делимого, а mod - делителя. И обычно таки нужен rem, а не mod.

P.S. В C, кстати, по крайней мере в С99, поведение % в этом отношении вообще implementation specific. :D


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 12 Июль, 2019 02:00 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
kemiisto писал(а):
В C, кстати, по крайней мере в С99, поведение % в этом отношении вообще implementation specific. :D
В С89, но не в С99, где это определено конкретно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Целочисленное деление
СообщениеДобавлено: Пятница, 12 Июль, 2019 02:11 

Зарегистрирован: Воскресенье, 03 Февраль, 2008 12:50
Сообщения: 249
Comdiv писал(а):
kemiisto писал(а):
В C, кстати, по крайней мере в С99, поведение % в этом отношении вообще implementation specific. :D
В С89, но не в С99, где это определено конкретно.

Ошибся, да. В С99 таки уже чётенько "truncation toward zero". Ну, не суть. :D А две разных операции есть ещё, как минимум, в Fortran и всякой "функцианальщине" типа там Scheme, Haskell. :)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 68 ]  На страницу Пред.  1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB