Автор Тема: А нужен ли в принципе контроль переполнения int типов  (Прочитано 13018 раз)

ddn

  • Jr. Member
  • **
  • Сообщений: 59
    • Просмотр профиля
Условие задачи всегда или почти всегда включает в себя требования по энергопотреблению. В частном, но не слишком частом, случае энергопотребление будет, по условию задачи, не ограничено.
А требование обработки данных по вполне конкретному принципу (по модулю либо с переполнением) условие задачи включает? Вам же не все равно, как данные будут обработаны, правильно или неправильно?

Если требования по энергопотреблению сводятся к его минимизации, то такая минимизация должна происходить в рамках прочих условий, правильной обработки данных например. Если требуется чтобы энергопотребление не превышало заданной величины, то данные опять же должны быть обработаны правильно, но такие условия задачи могут оказаться несовместными, и тогда программа не скомпилируется/не загрузится/будет нарушать условия задачи при работе.
« Последнее редактирование: Январь 03, 2013, 01:24:52 am от ddn »

ddn

  • Jr. Member
  • **
  • Сообщений: 59
    • Просмотр профиля
Да, и коль уж заговорили о переполнениях, выскажу старую свою мысль: система типов и у Оберона и у прочих современных ЯП (типа той же java например, да и плюсов и haskell'я) - дырявая.
Переполнения никак не связаны с типизацией, они связаны с реализацией математических операций и функций в ЯП. Переполнение, с высокоуровневой точки зрения, это изменение результата ЯП-операции или функции с математически правильного значения, если это значение выходит за пределы диапазона типа результата, на математически неправильное значение, но взятого в пределах указанного диапазона. Обычно это усечение старших битов.

В отличие от своих математических оригиналов, правильные ЯП-операции и функции, помимо типизации аргументов и результата, определены не для всех (математически допустимых) значений аргументов нужного типа. Например, правильно реализованные в ЯП математические операции сложения, вычитания и умножения int-типа определены не для всех пар int-значений.
Если же вместо сокращения области определения (вместо неопределенности результата) использовать выдачу неправильных значений но взятых в пределах диапазона, т.е. использовать переполнение, то это будет ошибочная реализация математики в ЯП.
Впрочем, никто не обязывает следовать правилу "тип результата = максимальный тип аргумента", тип результата можно взять достаточно большим, чтобы вместить значение результата от любых значений аргументов в пределах их типа.
Но, ни тот, ни другой, ни третий вариант не является нарушением строгой типизации.

У строго типизированных она почему-то запрещает например преобразование real->int, но при этом разрешает int+int.
Так int+int это не преобразование, а операция.

А ведь и то и другое может привести к одному и тому же - к переполнению/порче значения.
Порча значений относится не к ЯП, а к ошибочной реализации ЯП в компиляторе.
Если ЯП декларирует свои операции и функции без переполнения, а компилятор сует в них переполнение (место выдачи ошибки), то такой компилятор тоже является ошибочной реализацией языка.

Пусть у нас есть тип Int(N), где N - битность этого целочисленного типа.
Разные значения одного типа (одного объекта) не обязаны иметь одинаковую битность в машинном представлении. Значения одного типа это высокоуровневая категория и не привязаны к месту в памяти и ее размеру.

Тогда, очевидно в случае сложения двух чисел этого типа результат не будет иметь тип Int(N), он будет иметь тип Int(N+1).
При том условии, что не накладывается других ограничений кроме типа на значения аргументов, т.е. операция является всюду определенной. И если имеется подобная иерархия типов со вложенными диапазонами, не обязательно основанная на числе бит в представлении.
Тогда можно ввести правило "тип результата = минимальный тип, содержащий значение результата операции при любых допустимых значениях аргументов из диапазонов их типа", который вы назвали логическим типом.

Вообще же говоря (без такого правила), множество значений не привязано к определенному диапазонному типу. Потому невозможно определить тип результата по множеству принимаемых им значений, тип результата назначается. Произвольно. Операции INTEGER + INTEGER можно назначить тип результата хоть BYTE. Правда, операция не обязательно будет всюду определена.

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

Либо требовать рукотворного явного приведения типов. Типа a,b,c,d : int_4; a:=int_4(a+b+c+d); Только программировать в таком стиле будет не слишком удобно.
Что здесь имеется ввиду?
1. Тип результата операций опредялется по правилу "минимального типа", а затем функция int_4 проецирует (с проверкой) значение выражения к типу int_4.
2. int_4( + + + ) - единая конструкция (вызов функции), где роль разделителя аргуметов играет знак '+' (вместо запятой).
3. int_4 - опция компилятора, которая задает тип результата всех арифметических операций в подставленном выражении.
Отличаются тем, где генерируется ошибка.