Фэндом


8.0.jpg

Классы чиселПравить

8.diagramma.jpg

Одной из главных задач системы программирования Смолток является применение одной и той же метафоры для обработки информации настолько единообразно насколько это возможно. Метафора Смолтока, как было описано в предыдущих главах, это объекты которые взаимодействуют при помощи сообщений. Эта метафора очень похожа на метафору используемую в Симуле для реализации моделирования систем. Одной из наибольших проблем применения метафоры Смолтока ко всем аспектам системы программирования была арифметика. Симула использует метафору объектов/сообщений только для высокоуровневого взаимодействия в реализации модели. Для арифметики, как и для большинства алгоритмических управляющих структур, Симула полагается на встроенный язык программирования Алгол с его реализацией чисел, операторов и синтаксиса. Точка зрения утверждающая что сложение двух целых должно рассматриваться как посылку сообщения встретила определённое сопротивление на ранней стадии развития Смолтока. Опыт показал что преимущества такой единообразности в языке программирования перевешивает любые неудобства при реализации. Через несколько версий Смолтока была применена техника реализации уменьшающая накладные расходы на посылку сообщения для наиболее частых арифметических операций, поэтому цена единообразности не слишком высока.

Объекты представляющие числовые значения используются в большинстве систем Смолтока (как и в большинстве других языков программирования). Естественно числа используются для выполнения математических вычислений; они также используются в алгоритмах как номера, счётчики и обозначают состояния или условия (часто называемые флагами). Целые числа также используются как наборы битов над которыми выполняются логические операции.

Каждый вид числовых значений представлен классом. Классы чисел реализуются так чтобы все числа имели наиболее общий тип. Класс некоторого объекта числа определяется тем насколько нужна полная общность для представления его значения. Поэтому внешний протокол для всех объектов чисел наследуются от класса Число. У Числа есть три подкласса: Плавающее, Дробь и Целое. Целое имеет три подкласса: Малое целое, Большое положительное целое и Большое отрицательное целое. Целые числа предоставляют дополнительный протокол для интерпретирования чисел как последовательности битов. Этот протокол объявляется в классе Целое. Числа в системе это экземпляры классов Плавающее, Дробь, Малое целое, Большое положительное целое и Большое отрицательное целое. Классы Число и Целое объявляют общий протокол, но они не определяют представление конкретных числовых значений. Поэтому не создаётся экземпляров Числа и Целого.

В отличии от других объектов которые могут изменять своё внутреннее состояние, единственное состояние числа это его значение, которое никогда не изменяется. Объект 3, например, никогда не должен изменить своё состояние на 4, иначе могут наступить пагубные последствия.

Протокол классов чиселПравить

Число определяет протокол для всех классов чисел. Его сообщения поддерживают стандартные арифметические операции и сравнения. Большинство из этого должно быть реализовано подклассами Числа т.к. эти операции зависят от вида представления значения.

Протокол арифметических сообщений содержит обычные бинарные операции такие как +, -, * и / и несколько унарных сообщений и сообщений с ключевыми словами для вычисления модуля числа, изменения знака числа или целочисленного деления или нахождения остатка. Категории для арифметических сообщений следующие:

Протокол экземпляров Числа
арифметика
+ число Возвращает сумму получателя и аргумента, число.
- число Возвращает разность между получателем и аргументом, число.
* число Возвращает результат умножения получателя на аргумент, число.
/ число Возвращает результат деления получателя на аргумент, число. Заметьте что из за того что сохранятся наибольшая возможная точность, то если деление происходит с остатком, то результат будет экземляром Дроби.
// число Возвращает целое определённое как частное с округлением к минус бесконечности.
\\ число Возвращает целый остаток от деления с округлением к минус бесконечности. Это деление по модулю.
модуль Возвращает значение модуля получателя.
обратить Возвращает число со знаком противоположным знаку получателя.
дел: число Возвращает целое определяемое как целоечисленное деление с округлением к нулю.
ост: число Возвращает остаток от целочисленного деления с округлением к нулю.
обратное Возвращает 1 делёную на получателя. Если получатель навен 0 то вызывает сообщение об ошибке.

Несколько примеров.

предложение результат
1 + 10. 11
5.6 - 3. 2.6
5 - 2.6. 2.4
-4 модуль. 4
6 / 2. 3
7 / 2. (7/2), дробь с числителем 7 и знаменателем 2
7 обратное. (1/7), дробь с числителем 1 и знаменателем 7

Арифметические сообщения которые возвращают результат целочисленного деления и его остатка следуют двум соглашениям. По одному соглашению округление производится к нулю, по другому к минус бесконечности. Это даёт одинаковые результаты для положительных результатов т.к. ноль и минус бесконечность находятся в одном и том же направлении. Для отрицательных результатов, эти операции округляют результат в разных направлениях. Протокол Чисел предоставляет оба варианта.

Следующая таблица показывает взаимоотношение между селекторами.

результат округление к минус бесконечности округление к нулю
частное // дел:
остаток \\ ост:

Примеры:

предложение результат
6 дел: 2 3
7 дел: 2 3
(7 дел: 2) + 1 4
7 дел: 2 + 1 2
7 ост: 2 1
7 // 2 3
7 \\ 2 1
7 \\ 2 + 1 2
-7 дел: 2 -3
-7 ост: 2 -1
-7 // 2 -4
-7 \\ 2 1

Результат возвращаемый дел:, ост: или // всегда положительный если получатель и аргумент имеют одинаковые знаки, и отрицательный если их знаки различаются. \\ всегда возвращает положительное значение.

Дополнительные математические функции:

Протокол экземпляров Числа
математические функции
эксп Возвращает плавающее число равное экспоненте в степени получателя.
лн Возвращает натуральный логарифм получателя.
лог: число Возвращает логарифм получателя по основанию число.
пол лог: основание Возвращает пол от логарифма получателя с основанием, основание, где пол это ближайшее целое со стороны минус бесконечности.
в степени: число Возвращает получателя возведённого в степень аргумента, число.
в целоей степени: целое Возвращает получателя возведённого в степень аргумента, целое, где аргумент должен быть видом Целого.
квадратный корень Возвращает плавающее число равное квадратному корню получателя.
в квадрате Возвращает получателя умноженного на себя.

Примеры:

предложение результат
2.718284 лн. 1.0
6 эксп. 403.429
2 эксп. 7.38906
7.38906 лн. 1.99998
2 лог: 2. 1.0
2 пол лог: 2. 1
6 лог: 2. 2.58496
6 пол лог: 2. 2
6 в степени: 1.2. 8.58579
6 в целой степени: 2. 36
64 квадратный корень. 8.0
8 в квадрате. 64

Свойства чисел такие как чётность или нечётность и положительность и отрицательность можно проверить при помощи следующих сообщений.

Протокол экземпляров Числа
проверки
чётное Отвечает является ли получатель чётным числом.
нечётное Отвечает является ли получатель нечётным числом.
отрицательное Отвечает меньше ли 0 получатель.
положительное Отвечает больше ли либо равен 0 получатель.
строго положительное Отвечает больше ли 0 получатель.
знак Возвращает 1 если получатель больше 0, -1 если получатель меньше 0, иначе 0.

Свойства чисел которые связаны с округлением и усечение предоставляются следующим протоколом.

Number instance protocol
truncation and round off
потолок Возвращает целое ближайшее к получателю со стороны плюс бесконечности.
пол Возвращает целое ближайшее к получателю со стороны минус бесконечности.
усечённый Возвращает целое ближайшее к получателю со стороны нуля.
усечь до: число Возвращает ближайшее число кратное аргументу, число, со стороны нуля.
округлённый Возвращает ближайшее к получателю целое.
округлить до: число Возвращает ближайшее к получателю число кратное аргументу, число.

Когда Число нужно преобразовать в Целое, то можно использовать сообщение усечённый. Таким образом получаем:

предложение результат
16.32 потолок. 17
16.32 пол. 16
-16.32 пол. -17
-16.32 усечённый. -16
16.32 усечённый. 16
16.32 усечь до: 5. 15
16.32 усечь до: 5.1. 15.3
16.32 округлённый. 16
16.32 округлить до: 6. 18
16.32 округлить до: 6.3. 18.9

Протокол предоставляемый классом Число включает различные сообщения для преобразования чисел к другому виду объекта или к другой еденице измерения. Числа могут представляться в различных единицах измерения таких как градусы и радианы. Следующие два сообщения выполняют преобразование

Протокол экземпляров Числа
преобразование
градусы в радианы Подразумевается что получатель представлен в градусах. Возвращает преобразование градусов в радианы.
радианы в градусы Подразумевается что получатель представлен в радианах. Возвращает преобразование радианов в градусы.

Поэтому

30 градусы в радианы = 0.523599
90 градусы в радианы = 1.5708

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

В следующих примерах 30 градусов представлены как 0.523599 радиан, 90 градусов как 1.5708 радиан.

предложение результат
0.523599 син. 0.5
0.523599 кос. 0.866025
0.523599 тан. 0.57735
1.5708 син. 1.0
0.57735 арк тан. 0.523551
1.0 арк син. 1.5708

Когда какой либо вид Целого запрашивают добавить себя к другому виду Целого, возвращаемый результат естественно будет тоже видом Целого. То же самое верно для суммы двух Плавающих; класс результата будет тем же что и класс операндов. Если операнды это Малые целые и модуль их суммы слишком велик чтобы его можно было представить в виде Малого целого, то результатом станет Большое положительное целое или Большое отрицательное целое. Определение подходящего класса результата при различных классах операднов немного более сложно. Принцип положенный в основу таков что теряется как можно меньше информации и что коммутативные операции возвращают тот же результат не зависимо от того какой операнд является получателем а какой аргументом. Поэтому, например, 3.1 * 4 возвратит то же что и 4 * 3.1.

Подходящее представление для результата операции над числами с различными классами определяется с помощью значения общности присвоенного каждому классу. Класс имеющий большую общность будет иметь большее число своей оценки общности. Каждый класс должен уметь преобразовывать свои экземпляры в экземпляры больее общего класса с тем же значением. Мера общности используется для определения того кокой из операндов нужно преобразовать. Таким образом арифметические операции подчиняются закону коммутативности без потери информации о числах. Когда разница между двумя классами чисел are only a matter точности (где "точность" это мера информации предоставляемая числом), более точному классу присваивается большая общность в случаях когда точность не имеет значения (так Плавающее более общее чем Дробь).

Ирархия общности для видов числе в системе Смолток с болле общими классами записанными первыми:

Плавающее Дробь Большое положительное целое, Большое отрицательное целое Малое целое

Сообщния в протоколе Числа которые созданы для поддержки приведения видов содержатся в катерогии приведение.

Протокол экземпляров Числа
приведение
coerce: aNumber Answer a number representing the argument, aNumber, that is the same kind of Number as the receiver. This method must be defined by all subclasses of Number.
generality Answer the number representing the ordering

of the receiver in the generality hierarchy.

retry: aSymbol coercing: aNumber An arithmetic operation denoted by the symbol, aSymbol, could not be performed with the receiver and the argument, aNumber, as the operands because of the difference in representation. Coerce either the receiver or the argument, depending on which has the lower generality, and then try the arithmetic operation again. If the symbol is the equals sign, answer false if the argument is not a Number. If the generalities are the same, then retryxoercing: should not have been sent, so report an error to the user.

Поэтому если нужно выполнить 32.45 * 4, умножение Плавающего на Малое целое, то результат будет вычисляться предложением.

32.45 retry: #* coercing: 4

и аргумент 4 будет приведён к 4.0 (Плавающее имеет большую общность чем Малое целое). Затем произведение будет выполнено успешно.

Определение ирархии чисел в терминах общности численных величин раотает для видов числе предоставляемых в основной системе Смолток потому что общность транзитивна для этих видов чисел. Однако, общность не предоставляет техники для использования для всех видов чисел.

Интервалы (описаны подробно в главе 10) могут быть созданы при помощи одного или двух сообщений числу. Для каждого элемента такова интервала можно выполнить блок с элементом в качестве значеня аргумента блока.

Протокол экземпляров Числа
интервалы
до: конец Возвращает Интервал от получателя до аргумента, конец, с промежутком между элементами равным еденице.
до: конец через: шаг Возвращает Интервал от получателя до аргумента, конец, с промежутком между элементами равным аргументу шаг.
до: конец делать: блок Создаёт Интервал от получателя до аргумента, конец, с шагом 1. Выполняет аргумент, блок, для каждого элемента интервала.
до: конец через: шаг делать: блок Создаёт Интервал от получателя до аргумента, конец, с шагом шаг. Выполняет аргумент, блок, для каждого элемента интервала.

Поэтому если выполнить

а0.
10 до: 100 через: 10 делать: [ :каждый | аа + каждый. ].

то значение переменной а будет равно 550.

Если а это ряд #('один' 'два' 'три' 'четыре' 'пять'), то к каждому элемент уэтого ряда можно получить доступ при помощи номера который принадлежит интервалу от 1 до размера ряда. Следующее предложение изменяет каждый элемент так чтобы остался только первый знак.

1 до: а размер делать: [ :номер | а от: номер пом: ((а от: номер) от: 1). ].

В результате ряд станет таким: #('о' 'д' 'т' 'ч' 'п'). Заметьте что подобно рядам, к элементам цепи можно получить доступ используя сообщение от: и от:пом:. Сообщения объектам подобныйм рядам и цепям детально рассматриваются в главах 9 и 10.

Классы Плавающее и ДробьПравить

Классы Плавающее и Дробь это два представления не целых числовых значений. Плавающее представляет приближённые действительные числа; они представляют точность около 6 десятичных знаков с диапазоном значений между плюс или минут 10 возведённым в степень плюс или минус 32. Вот несколько примеров:

8.0
13.3
0.3
2.5э6
1.27э-30
-12.987654э12

Дроби представляют рациональные числа которы всегда точные. Все арифметические операции с Дробями возвращают простые дороби.

Экземпляры Плавающего могут быть созданы при помощи литерала (например 3.14159) или как результат арифметических операций, один аргумент которых это другое Плавающее.

Экземпляры Дроби могут быть созданы в результате арифметической операции если один из операндов это дробь и другой не является плавающим. (Если один из аргументов это плавающее число, то результат тоже будет плавающее число т.к. общность плавающих чисел выше чем у дробей). Экземпляры Дроби также могут быть созданы при помощи операции деления (/) произведённой над двумя Целыми, если её результат не целое число. В дополнение к этим способам протокол Дроби поддерживает сообщение создания экземпляра числитель: целое числ знаменатель: целое знам.

Плавающее отвечает на сообщение пи возвращающее соответствующую константу. Этот класс добавляет протокол протоколы усечения и округления для возврата дробной и целой части получателя (дробная часть и целая часть), и добавляет протокол преобразования для преобразования получателя в Дробь (как дробь). Класс Дробь тоже добавляет протокол преобразования для преобразования получателя в Плавающее (как плавающее).

Классы целыхПравить

Класс Целое добавляет протокол специфичный для целых чисел. У него есть три подкласса. Один из них то класс Малое целое, который является классом важного диапазона значений с экономным использованием памяти которые часто встречаются в вычислениях и при нумерации. Представление охватывает диапазон который немного меньше чем машинное слова. Большие челые, которые представляются экземплярами Большого положительного целого и Большого отрицательного целого в зависимости от знака числа, не имеют предела их величина. Цена этой общности - большее время на вычисления. Поэтому если результат арифметической операции для больших целых это целое которое можно представить при помощи малого целого, то результат будет малым целым.

В дополнение к сообщенимям унаследованным от класса Число, класс Целое добавляет протокол преобразования (как знак, как плавающее и как дробь), также печать (печатать в: поток основание: о, основание: целое основание), и протокол перебора. Поэтому 8 основание: 2 это 2о1000.

Для перебора, можно многократно выполнить блок число раз равное целому используя сообщение раз повторить: блок. Рассмотрим пример

   а1.
   10 раз повторить: [ аа + а. ].

где у блока нет аргументов. Конечное значение а это 210, или 1024.

Класс Целое предоставляет протоколы для факторизация и проверки делимости которые не определены для чисел в целом.

Протокол экземпляров Целого
факторизация и делимость
факториал Возвращает факториал получателя. Получатель должен быть не меньше 0.
нод: целое Возвращает наибольший общий делитель получателя и аргумента, целое.
нок: целое Возвращает наименьшее общее кратное получателя и аргумента, целое.

Примеры

предложение результат
3 факториал. 6
55 нод: 30. 5
6 нок: 10. 30

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

Протокол экземпляров Целого
действия с битами
вся маска: целое Рассматривает аргумен целое как битовую маску. Отвечает все ли быти равные 1 в маске равны 1 в получателе.
любой из маски: целое Рассматривает аргумен целое как битовую маску. Отвечает есть ли хотябы один бит который равный 1 и в маске и в получателе.
не маска: целое Рассматривает аргумен целое как битовую маску. Отвечает все ли биты равные 1 в маске равны 0 в получателе.
побитовое и: целое Возвращает целое чьи биты это логическое и соответствующих битов получателя и аргумента, целое.
побитовое или: целое Возвращает целое чьи биты это логическое или соответствующих битов получателя и аргумента, целое.
побитовое искл или: целое Возвращает целое чьи биты это логическое исключающее или соответствующих битов получателя и аргумента, целое.
обратить биты Возвращает целое чьи биты это дополнение до 2 получателя.
старший бит Возвращает номер старшего бита в двоичном представлении получателя.
сдвинуть биты: целое Возвращает целое чьё значение (в представлении дополнения до двух) сдвинуто влево на количество бит указанных аргументом, целое. Отрицательный аргумент сдвигает вправо. При сдвиге влево справа подставляются нули. При сдвиге вправо происходит заполнение битом знака.

Приведём несколько примеров. Заметьте что по умолчанию основание для печати равно 10.

выражение результат
2о111000111000111 29127
2о101010101010101. 21845
2о101000101000101 20805
2о000111000111000 3640
29127 вся маска: 20805 истина
29127 вся маска: 21845 ложь
29127 любой из маски: 21845 истина
29127 не маска: 3640 истина
29127 побитовое и: 3640 0
29127 побитовое или: 3640 32767
32767 основание: 2 2о111111111111111
29127 побитовое или: 21845 30167
30167 основание: 2 2о111010111010111
3640 сдвинуть биты: 1 7280

Класс Случайное число: генератор случайных чиселПравить

Многим программам нужен случайный выбор числа. Например, случайные числа полезны в статистике и алгоритмах шифрования. Класс Случайное число это генератор случайных чисел который включён в систему Смолток. Он предоставляет простой способ получения последовательности случайных чисел которые равномерно распределены на интервале между 0.0 и 1.0 (не включая границы).

Экземпляр класса Случайное число это источник из которого получаются случайные числа. Он инициализируется псевдо случайным образом. Когда нужно получить новое случайное число то экземпляру Случайного числа посылается сообщение следующий.

Генератор случайных чисел может быть создан при помощи следующего предложения.

случСлучайное число новый.

Предложение

случ следующий.

может быть выполнено когда понадобится новое случайное число. Ответ на это сообщение это число (Плавающее) между 0.0 и 1.0.

Реализация метода следующий основана на Lehmer's linear congruential method описанном Кнутом в первом томе (Д.Э. Кнут, Искусство программирования: основные алгоритмы Том 1)

реализация Сквика 3.9
next
   (seedself nextValue) / m.
nextValue
   | lo hi aLoRHi answer |
   hi(seed quo: q) asFloat.
   loseed - (hi * q).
   aLoRHia * lo - (r * hi).
   answeraLoRHi > 0.0 ifTrue: [ aLoRHi. ] ifFalse: [ aLoRHi + m. ].
   answer.

Также можно послать экземпляру класса Случайное чило сообщение следующий: целое, чтобы получить Упорядоченный набор случайных чисел размером целое.

Допустим мы хотим выбрать одно из 10 целых 1, ..., 10, используя генератор случайных числе. Предложение которое нужно выполнить:

(случ следующий * 10) усечённый + 1.

Здесь

выражение результат
случ следующий Случайное число между 0 и 1.
случ следующий * 10 Случайное число между 0 и 10.
(случ следующий * 10) усечённый Целое которое больше либо рабоно 0 и меньше либо рабоно 9.
(случ следующий * 10) усечённый + 1 Целое которое больше либо рабоно 0 и меньше либо рабоно 10.

Обнаружено использование расширения AdBlock.


Викия — это свободный ресурс, который существует и развивается за счёт рекламы. Для блокирующих рекламу пользователей мы предоставляем модифицированную версию сайта.

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

Также на Фэндоме

Случайная вики