OberonCore https://forum.oberoncore.ru/ |
|
LONGINT => INTEGER https://forum.oberoncore.ru/viewtopic.php?f=35&t=6580 |
Страница 1 из 1 |
Автор: | olegr [ Суббота, 07 Март, 2020 19:39 ] |
Заголовок сообщения: | LONGINT => INTEGER |
Здравствуйте, помогите разобраться, был уверен, что если переменной типа 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 ? Что не так? |
Автор: | Иван Денисов [ Суббота, 07 Март, 2020 20:02 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
Промежуточные вычисления INTEGER компилятор размещает в INTEGER. Ну и только в финале переводит к типу LONGINT. Если планируете, что будут длинные результаты, то лучше переменные делайте длинными целыми. Или преобразуйте в LONG прямо в выражении. Вот так: Код: total := LONG(block) * LONG(sector) * LONG(number);
|
Автор: | Иван Денисов [ Суббота, 07 Март, 2020 20:09 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
В этом плане вирт навел порядок в новой версии Оберона, запретив в принципе автоматическое преобразование типов. Так то он и длинные типы убрал и короткие. Но вот скажем явно надо приводить типы целые к действительным или действительные к целым. Так что невозможно применить операцию "/" к целым числам, например. Надо сначала перевести его в действительное. Код: VAR i: INTEGER; b: REAL; BEGIN i := 50; b := FLT(i) / 5.0; В Компонентном Паскале не так строго. Но из-за этого надо держать такие преобразования в голове. Еще и преобразования длинных типов иметь в виду, то с чем вы столкнулись. Но это всё равно намного легче, чем в языках с повсеместным преобразованием всего во всё. |
Автор: | olegr [ Суббота, 07 Март, 2020 20:14 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
т.е. внутри ББ при вычислении выражений из INTEGER создается внутренний буфер того же типа? |
Автор: | Иван Денисов [ Суббота, 07 Март, 2020 20:17 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
olegr писал(а): т.е. внутри ББ при вычислении выражений из INTEGER создается внутренний буфер того же типа? Что-то вроде того. Тут вам компиляторщики лучше ответят, "буфер" там или "стек" или как это правильно называется... |
Автор: | olegr [ Суббота, 07 Март, 2020 20:18 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
Спасибо! Все понял. |
Автор: | Info21 [ Суббота, 07 Март, 2020 20:24 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
При вычислении с типами не длиннее INTEGER все промежуточные значения -- INTEGER. В Вашем случае достаточно поставить LONG на крайний левый операнд. Операции одного уровня выполняются слева направо, и если хоть один LONG, то второй будет приведён к LONG автоматически. Хотя для надёжности можно сделать и как посоветовал ИАД. |
Автор: | adimetrius [ Суббота, 07 Март, 2020 21:00 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
Иван Денисов писал(а): В Компонентном Паскале не так строго. Но из-за этого надо держать такие преобразования в голове. Еще и преобразования длинных типов иметь в виду, то с чем вы столкнулись. Но это всё равно намного легче, чем в языках с повсеместным преобразованием всего во всё. Голова - для других, более приятных и творческих вещей, нехорошо там всякие длинные преобразования держать. А что если "устрожить" эти правила КП как опцию компилятора? Я у себя по умолчанию включил все проверки диапазонов. |
Автор: | Trurl [ Суббота, 07 Март, 2020 21:05 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
Кстати, пример подтверждает, что лучше бы контроль переполнения был включен по умолчанию. |
Автор: | olegr [ Суббота, 07 Март, 2020 21:15 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
adimetrius писал(а): Голова - для других, более приятных и творческих вещей, нехорошо там всякие длинные преобразования держать. А что если "устрожить" эти правила КП как опцию компилятора? Я у себя по умолчанию включил все проверки диапазонов. Как будет выглядеть проверка диапазонов для моего примера? |
Автор: | Иван Денисов [ Суббота, 07 Март, 2020 21:18 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
olegr, чтобы во время выполнения программа аварийно остановилась при переполнении и сообщила об ошибке, вы можете вот такой командой компилировать ваш модуль Код: DevCompiler.CompileThis Kern+ Если хотите, чтобы это правило строгой проверки выполнялось всегда при компиляции через меню, вот так возможно добавить настройку компилятора перед его вызовом. Код: DevCompiler.CompileOpt('+') Файлы меню править удобно через меню Info/Menus UPD2. Убрал неверную картинку. |
Автор: | olegr [ Суббота, 07 Март, 2020 21:32 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
Спасибо Иван, жаль нет доки по опциям компилятора ББ в стандартном дистрибутиве. |
Автор: | adimetrius [ Суббота, 07 Март, 2020 21:36 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
olegr писал(а): adimetrius писал(а): Голова - для других, более приятных и творческих вещей, нехорошо там всякие длинные преобразования держать. А что если "устрожить" эти правила КП как опцию компилятора? Я у себя по умолчанию включил все проверки диапазонов. Как будет выглядеть проверка диапазонов для моего примера? Будет авост. И вы узнаете об ошибке сразу, а не будете гадать - почему это у меня какое-то непонятное значение в LONGINT? VAR l: LONGINT; x: INTEGER; BEGIN x := MAX(INTEGER); l := x + 1; |
Автор: | Иван Денисов [ Суббота, 07 Март, 2020 21:41 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
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" |
Автор: | olegr [ Суббота, 07 Март, 2020 21:51 ] |
Заголовок сообщения: | Re: LONGINT => INTEGER |
Да теперь вижу, есть. Там еще не читал… |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |