Как ДЕЙСТВИТЕЛЬНО делать математику с NSNumbers? (Реализация LISP в Obj-C) - PullRequest
8 голосов
/ 16 июня 2011

вдохновлено Clojure и Питер Норвиг

Я пытался реализовать простой Lisp в obj-c. У меня есть много основ (включая некоторую классную интеграцию какао, похожую на Clojure), и я хотел бы перейти к арифметике.

Небольшая предыстория о том, как я реализовал это до сих пор: я использую крошечный класс "Scope", который является просто NSMutableDictionary для локальных переменных, с указателем на родительский "Scope". (AKA, я вынужден хранить только предметы.)

Я анализирую числа по следующему правилу: обычное число, такое как 2 или 2.7, преобразуется в [NSNumber numberWithIneger:] или [NSNumber numberWithDouble:]. Но для интеграции какао вы также можете сделать что-то вроде 2i или 4U, чтобы создать NSNumber с определенным скалярным типом. (Я также создал категорию вокруг NSObject и создал новый метод performSelector:withObjects:, который разумно распаковывает аргументы и создает резервную копию возвращаемого типа, чтобы фактически сделать это полезным)

У меня есть специальная форма, которая выглядит следующим образом: (static Math add: 1 2 3 4), которая превращается в вызов метода obj-c, который выглядит следующим образом: [Math add:args]

Учитывая все это, мой вопрос ко всем вам, замечательные люди: каков хороший способ реализации метода "add:"?

Я надеялся сделать что-то похожее на то, как я полагаю, что clojure делает (использует, чтобы делать?) Это, реализуя множество методов, таких как add:(int)x to:(long)y, add:(long)x to:(float)y и т. Д., И т. Д., Используя все возможные комбинации и сокращая по списку аргументов попарно добавляя все. Но, конечно, obj-c не поддерживает переопределяющие методы, подобные этому. Помимо того, что я ограничиваю себя только добавлением NSIntegers и парных чисел, могу ли я сделать какую-то хитрость, чтобы добраться туда, куда я хочу? Мне даже не важно, насколько это эффективно (хотя это всегда плюс!)

1 Ответ

1 голос
/ 16 июня 2011

Простой метод: просто делайте все числа в double s при выполнении арифметики и игнорируйте проблемы приведения и точности.

Другой вариант - использовать NSDecimalNumber вместо NSNumber везде. Есть метод +[NSDecimalNumber decimalNumberWithString], который вы можете использовать для бокса, а также есть методы для выполнения арифметики с несколькими NSDecimalNumber с. Конечно, у вас больше накладных расходов, но я думаю, что сырая производительность не является первостепенной задачей.

...