Я недавно учусь быстро, но у меня есть основная проблема, на которую я не могу найти ответ
Я хочу получить что-то вроде
var a:Int = 3
var b:Int = 3
println( pow(a,b) ) // 27
но функция pow может работать только с двойным числом, она не работает с целым числом, и я даже не могу привести int к удвоению чем-то вроде Double (a) или a.double () ...
Почему он не обеспечивает степень целого числа? он обязательно вернет целое число без двусмысленности! и почему я не могу преобразовать целое число в двойное? просто измените 3 на 3,0 (или 3,00000 ... что угодно)
если у меня есть два целых числа, и я хочу выполнить операцию питания, как я могу сделать это плавно?
Спасибо!
Ответы:
Если хотите, вы можете объявить,
infix
operator
чтобы это сделать.Я использовал две вставки, поэтому вы все еще можете использовать оператор XOR .
Обновление для Swift 3
В Swift 3 «магическое число»
precedence
заменено наprecedencegroups
:источник
infix operator ^^ { precedence 160 } func ^^
... и так далееfunc p(_ b: Bool) -> Double { return b?-1:1 }
?Помимо того, что в ваших объявлениях переменных есть синтаксические ошибки, это работает именно так, как вы ожидали. Все, что вам нужно сделать, это привести
a
иb
к Double и передать значения вpow
. Затем, если вы работаете с 2 Ints и хотите вернуть Int на другой стороне операции, просто верните значение Int.источник
3 ** 3
. Иногда мне нужно решить проблему алгоритма с помощью Swift, это действительно болезненно по сравнению с использованием Python.Иногда приведение
Int
кDouble
не является жизнеспособным решением. На некоторых величинах это преобразование приводит к потере точности. Например, следующий код не возвращает то, что вы могли бы интуитивно ожидать.Если вам нужна высокая точность и вам не нужно беспокоиться об отрицательных показателях, которые, как правило, нельзя решить с помощью целых чисел, тогда эта реализация алгоритма хвостовой рекурсии возведения в степень возведения в квадрат - ваш лучший выбор. Согласно этому ответу SO , это «стандартный метод модульного возведения в степень для огромных чисел в асимметричной криптографии».
Примечание: в этом примере я использовал общий
T: BinaryInteger
. Это значит, что вы можете использоватьInt
илиUInt
или любой другой целочисленный тип.источник
Int
или вы можете заставить эти вещи называть эту бесплатную функцию - как вам угодно.Если вы действительно хотите реализовать «только Int» и не хотите принуждения к / от
Double
, вам необходимо реализовать ее. Вот тривиальная реализация; есть более быстрые алгоритмы, но это будет работать:В реальной реализации вам, вероятно, понадобится проверка ошибок.
источник
Double(Int.max - 1) < Double(Int.max)
Swift 3 REPL, и вы можете быть удивлены.reduce
вызова.return (2...power).reduce(base) { result, _ in result * base }
немного подробнее
swift - двоичные выражения
источник
Если вы не склонны к перегрузке оператора (хотя
^^
решение, вероятно, понятно для тех, кто читает ваш код), вы можете быстро реализовать:источник
mklbtz прав в отношении возведения в степень возведения в квадрат как стандартного алгоритма для вычисления целочисленных степеней, но хвостовая рекурсивная реализация алгоритма кажется немного запутанной. См. Http://www.programminglogic.com/fast-exponentiation-algorithms/ для нерекурсивной реализации возведения в степень возведением в квадрат в C. Я попытался перевести это на Swift здесь:
Конечно, это можно придумать, создав перегруженный оператор для его вызова, и его можно переписать, чтобы сделать его более универсальным, чтобы он работал со всем, что реализует
IntegerType
протокол. Чтобы сделать его общим, я бы, вероятно, начал с чего-то вродеНо, наверное, увлекаюсь.
источник
BinaryInteger
.IntegerType
устарела.Или просто :
источник
Объединение ответов в перегруженный набор функций (и использование «**» вместо «^^», как в некоторых других языках - для меня яснее):
При использовании Float вы можете потерять точность. Если вы используете числовые литералы и сочетание целых и нецелых чисел, по умолчанию вы получите Double. Мне лично нравится возможность использовать математическое выражение вместо функции типа pow (a, b) по стилистическим соображениям / удобочитаемости, но это только я.
Любые операторы, которые могут вызвать ошибку pow (), также будут вызывать ошибку этими функциями, поэтому бремя проверки ошибок все равно лежит на коде, использующем функцию мощности. KISS, ИМХО.
Использование встроенной функции pow () позволяет, например, извлекать квадратные корни (2 ** 0,5) или обратные (2 ** -3 = 1/8). Из-за возможности использования обратных или дробных показателей я написал весь свой код так, чтобы он возвращал тип Double по умолчанию функции pow (), который должен возвращать наибольшую точность (если я правильно помню документацию). При необходимости это может быть преобразовано в тип Int или Float или что-то еще, возможно, с потерей точности.
источник
Оказывается, можно и использовать
pow()
. Например, вы можете использовать следующее, чтобы выразить 10 до 9-го.Наряду с
pow
,powf()
возвращаетfloat
вместоdouble
. Я тестировал это только на Swift 4 и macOS 10.13.источник
Для расчета
power(2, n)
просто используйте:источник
Версия Swift 4.x
источник
В Swift 5:
Используйте как это
Благодаря ответу @Paul Buis.
источник
Массив (повторение: a, count: b) .reduce (1, *)
источник
Функция pow на основе Int, которая вычисляет значение напрямую через битовый сдвиг для базы 2 в Swift 5:
(Убедитесь, что результат находится в диапазоне Int - это не проверяет случай выхода за границы)
источник
Другие ответы хороши, но при желании вы также можете сделать это с
Int
расширением, если показатель степени положительный.источник
Пытаясь совместить перегрузку, я пытался использовать дженерики, но не смог заставить их работать. Я наконец решил использовать NSNumber вместо того, чтобы пытаться перегрузить или использовать дженерики. Это упрощается до следующего:
Следующий код представляет собой ту же функцию, что и выше, но реализует проверку ошибок, чтобы увидеть, можно ли успешно преобразовать параметры в двойные.
источник
Swift 5
Я был удивлен, но правильного решения здесь не нашел.
Это мое:
Пример:
источник
Мне это нравится больше
источник
Пример:
источник