OberonCore

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

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




Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
 Заголовок сообщения: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 19:39 

Зарегистрирован: Суббота, 07 Март, 2020 18:18
Сообщения: 6
Здравствуйте,
помогите разобраться, был уверен, что если переменной типа LONGINT присвоить выражение с переменными типа INTEGER, то результат будет в диапазоне допустимых значений типа LONGINT, вот пример где я запутался.
Код:
MODULE Kern;
IMPORT L := StdLog;

PROCEDURE Do*;
VAR
   block,sector,number:   INTEGER;
   total:   LONGINT;
BEGIN

   L.Int(MAX(INTEGER)); L.Ln;
   L.Int(MAX(LONGINT)); L.Ln;

   block := 8; sector := 512; number := 10000000;
   total := block * sector * number;
   L.Int(total); L.Ln;
   
END Do;

BEGIN

CLOSE

END Kern.

Kern.Do

результат вывода в журнал :
2147483647 - это MAX(INTEGER)
9223372036854775807 - это MAX(LONGINT)
-1989672960 - а это как ведь должен же быть 40960000000 или total: LONGINT стал INTEGER ?


Что не так?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 20:02 
Аватара пользователя

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

Если планируете, что будут длинные результаты, то лучше переменные делайте длинными целыми. Или преобразуйте в LONG прямо в выражении.

Вот так:
Код:
total := LONG(block) * LONG(sector) * LONG(number);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 20:09 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
В этом плане вирт навел порядок в новой версии Оберона, запретив в принципе автоматическое преобразование типов. Так то он и длинные типы убрал и короткие. Но вот скажем явно надо приводить типы целые к действительным или действительные к целым. Так что невозможно применить операцию "/" к целым числам, например. Надо сначала перевести его в действительное.

Код:
VAR i: INTEGER; b: REAL;
BEGIN
i  := 50;
b := FLT(i) / 5.0;


В Компонентном Паскале не так строго. Но из-за этого надо держать такие преобразования в голове. Еще и преобразования длинных типов иметь в виду, то с чем вы столкнулись. Но это всё равно намного легче, чем в языках с повсеместным преобразованием всего во всё.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 20:14 

Зарегистрирован: Суббота, 07 Март, 2020 18:18
Сообщения: 6
т.е. внутри ББ при вычислении выражений из INTEGER создается внутренний буфер того же типа?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 20:17 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
olegr писал(а):
т.е. внутри ББ при вычислении выражений из INTEGER создается внутренний буфер того же типа?

Что-то вроде того. Тут вам компиляторщики лучше ответят, "буфер" там или "стек" или как это правильно называется...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 20:18 

Зарегистрирован: Суббота, 07 Март, 2020 18:18
Сообщения: 6
Спасибо! Все понял.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 20:24 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
При вычислении с типами не длиннее INTEGER все промежуточные значения -- INTEGER.

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

Хотя для надёжности можно сделать и как посоветовал ИАД.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 21:00 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 660
Иван Денисов писал(а):
В Компонентном Паскале не так строго. Но из-за этого надо держать такие преобразования в голове. Еще и преобразования длинных типов иметь в виду, то с чем вы столкнулись. Но это всё равно намного легче, чем в языках с повсеместным преобразованием всего во всё.


Голова - для других, более приятных и творческих вещей, нехорошо там всякие длинные преобразования держать.
А что если "устрожить" эти правила КП как опцию компилятора? Я у себя по умолчанию включил все проверки диапазонов.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 21:05 

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 21:15 

Зарегистрирован: Суббота, 07 Март, 2020 18:18
Сообщения: 6
adimetrius писал(а):
Голова - для других, более приятных и творческих вещей, нехорошо там всякие длинные преобразования держать.
А что если "устрожить" эти правила КП как опцию компилятора? Я у себя по умолчанию включил все проверки диапазонов.


Как будет выглядеть проверка диапазонов для моего примера?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 21:18 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
olegr, чтобы во время выполнения программа аварийно остановилась при переполнении и сообщила об ошибке, вы можете вот такой командой компилировать ваш модуль
Код:
DevCompiler.CompileThis Kern+


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

Код:
DevCompiler.CompileOpt('+')


Файлы меню править удобно через меню Info/Menus
UPD2. Убрал неверную картинку.


Последний раз редактировалось Иван Денисов Суббота, 07 Март, 2020 21:53, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 21:32 

Зарегистрирован: Суббота, 07 Март, 2020 18:18
Сообщения: 6
Спасибо Иван, жаль нет доки по опциям компилятора ББ в стандартном дистрибутиве.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 21:36 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 660
olegr писал(а):
adimetrius писал(а):
Голова - для других, более приятных и творческих вещей, нехорошо там всякие длинные преобразования держать.
А что если "устрожить" эти правила КП как опцию компилятора? Я у себя по умолчанию включил все проверки диапазонов.


Как будет выглядеть проверка диапазонов для моего примера?


Будет авост. И вы узнаете об ошибке сразу, а не будете гадать - почему это у меня какое-то непонятное значение в LONGINT?

VAR l: LONGINT; x: INTEGER;
BEGIN x := MAX(INTEGER); l := x + 1;


Последний раз редактировалось adimetrius Суббота, 07 Март, 2020 23:27, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 21:41 
Аватара пользователя

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

Это есть в стандартном дистрибутиве, в документе P-S-I (Platform-Specific Issues).

Вот так будет правильно в меню. Выше без проверки опубликовал. Теперь проверил.
DevCompiler.CompileOpt('+') не включает опцию, а именно компилирует оказывается.

Код:
   SEPARATOR
   "#Dev:&Compile"   "K"   "DevCompiler.CompileOpt('+')"   "TextCmds.FocusGuard"
   "#Dev:&Compile And Unload"   ""   "DevCompiler.CompileOpt('+'); DevDebug.Unload"   "TextCmds.FocusGuard"


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: LONGINT => INTEGER
СообщениеДобавлено: Суббота, 07 Март, 2020 21:51 

Зарегистрирован: Суббота, 07 Март, 2020 18:18
Сообщения: 6
Да теперь вижу, есть. Там еще не читал…


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

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


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

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


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

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