![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Тип целого для результата вычислений [D4]
Германн © (2006-12-24 01:53:00)Дано:
ShowMessage(IntToStr(арифметическое выражение, которое может включать в себя все арифметические операции производимые над набором переменных разного целочисленного типа ));
Набор переменных может включать в себя типы Byte, Smallint, Longint, Integer и т.д.
Теперь вопрос:
Есть ли какие-то "жесткие правила" по тому, какой тип будет у того значения результата вычислений, который будет обрабатываться функцией IntToStr? Если есть, то где они описаны?
Может я "дую на воду", но что-то мне мой склероз напоминает о проблемах, которые я когда-то, где-то видел. А сейчас, сегодня, надо либо знать точно, либо "подстилать соломку" типа Integer(n).
Sha (2006-12-25 09:39:00) [1]> ors_archangel © (25.12.06 01:51) [8]
> Насколько я помню, у IntToStr есть overload для Int64, так что всё ок
Я не сомневался )
ors_archangel (2006-12-25 01:51:00) [2]
> [6] Sha
> ShowMessage(IntToStr(int64(MaxInt)*MaxInt));
Насколько я помню, у IntToStr есть overload для Int64, так что всё ок
Германн (2006-12-25 01:25:00) [3]Короче. Наплевал я на все высокие материи и просто "в лоб" применил Integer() к первой переменной с учётом приоритета арифметических операций. Вроде работает. Но терзают меня смутные сомнения. Где же я когда-то "обжегся на молоке"? Или это мой склероз подсовывает мне глюки? :-)
Sha (2006-12-24 12:22:00) [4]> BanserAnt (24.12.06 11:46) [5]
Интересно, что же выдаст такой код :)
ShowMessage(IntToStr(int64(MaxInt)*MaxInt));
BanserAnt (2006-12-24 11:46:00) [5]Функция IntToStr принимает только Integer, но беспокоиться самому не надо, компилятор преобразует аргумент к данному типу автоматически
Германн (2006-12-24 03:00:00) [6]
> ors_archangel © (24.12.06 02:51) [3]
>
> Жёских правил не знаю для таких выражений...
Спасибо за участие! И спасибо вообще!
ors_archangel (2006-12-24 02:51:00) [7]Жёских правил не знаю для таких выражений, но практика (CPU) показывает, что smallintпреобразовывается в integerперед использованием в выражении (при помощи movsx), даже если это константа типа smallint, это вполне обосновано: 16-битный код (для типов smallint, word) отличается от 32-битного ( integer, cardinal) префиксом 16-битности (66h, например dec ecx(опкод уменьшения значения регистра счётчика на единицу, кто не в курсах) имеет код 49h, а dec cx- 66h 49h), т.о. работают с немного меньшей скоростью (т.к. ухудшается кэширование и выборка) и занимают хоть и чуть-чуть, но больше места, поэтому легче как можно раньше преобраховать smallintили wordв integerили cardinal, а потом уже баловаться с ними, поэтому я лично никогда не использую smallintили word, исключая случаи с var/ in/ out-параметрами и массивами (в последних, чисто для экономии памяти)
Германн (2006-12-24 02:33:00) [8]
> ors_archangel © (24.12.06 02:21) [1]
Спасибо. Но!!!
Теперь вариант. В "арифметическом выражении" есть только одна переменная. Типа Smallint. Её значение 4000. Умножаем её на 10 и делим целочисленно на 8 (n*10 div 8) .
Что получим в результате выполнения ShowMessage(IntToStr(n*10 div 8)) ?
ors_archangel (2006-12-24 02:21:00) [9]Тип результата в данном случае будет определяться так: если в выражении есть только тип byte, тогда результат будет byteи так для каждого типа: smallint, integer, теперь, если в выражении, кроме, допустим smallintесли ещё integer, то результат будет типа integer, т.к. множество значения типа integerвключает множество значений типа smallint, но не наоборот, это - общий принцип, в частности, он приводит к тому, что если мы комбинируем в выражении типы cardinal(0..2^32-1) и integer(-2^31..2^31-1), то ни один из них "не включает" другой, соответсвенно, выражение приобретает тип int64(-2^63..2^63-1), множество значений которого включает их оба, но при этом генерируется "плохой" код, т.к. целочисленная 64-битная арифметика до сих пор не поддерживается x86, этот код будет иметь неоправдано большой размер и скорость при этом также весьма и весьма падает, поэтому в таких случаях желательно специально приводить переменные типа cardinal к integer (либо наоборот, в зависимости от смысла), либо не использовать такие переменные в одном математическом выражении.
Замечание: Для D2-D7 Longint = Integer