Estou aprendendo rápido recentemente, mas tenho um problema básico que não consigo encontrar uma resposta
Eu quero conseguir algo como
var a:Int = 3
var b:Int = 3
println( pow(a,b) ) // 27
mas a função pow pode funcionar apenas com número duplo, não funciona com número inteiro, e eu não consigo nem converter o int para dobrar por algo como Double (a) ou a.double () ...
Por que ele não fornece a potência do inteiro? ele definitivamente retornará um número inteiro sem ambigüidade! e por que não consigo converter um inteiro em duplo? basta alterar 3 para 3.0 (ou 3.00000 ... qualquer)
se eu tenho dois inteiros e quero fazer a operação de energia, como posso fazer isso sem problemas?
Obrigado!
Respostas:
Se quiser, você pode declarar um
infix
operator
para fazer isso.Usei dois circunflexos para que você ainda possa usar o operador XOR .
Atualização para Swift 3
No Swift 3, o "número mágico"
precedence
é substituído porprecedencegroups
:fonte
infix operator ^^ { precedence 160 } func ^^
... e assim por diantefunc p(_ b: Bool) -> Double { return b?-1:1 }
?Além de que suas declarações de variáveis têm erros de sintaxe, isso funciona exatamente como você esperava. Tudo que você tem a fazer é lançado
a
eb
para Double e passar os valores parapow
. Então, se você estiver trabalhando com 2 Ints e quiser um Int de volta do outro lado da operação, basta lançar de volta para Int.fonte
3 ** 3
. Às vezes, preciso resolver problemas de algoritmo usando Swift, é realmente doloroso em comparação com o uso de Python.Às vezes, lançar um
Int
em aDouble
não é uma solução viável. Em algumas magnitudes, há perda de precisão nessa conversão. Por exemplo, o código a seguir não retorna o que você pode esperar intuitivamente.Se você precisa de precisão em altas magnitudes e não precisa se preocupar com expoentes negativos - que geralmente não podem ser resolvidos com inteiros de qualquer maneira - então esta implementação do algoritmo de exponenciação por quadratura recursiva de cauda é sua melhor aposta. De acordo com esta resposta do SO , este é "o método padrão para fazer exponenciação modular para grandes números em criptografia assimétrica."
Nota: neste exemplo, usei um genérico
T: BinaryInteger
. Isso é para que você possa usarInt
ouUInt
ou qualquer outro tipo de número inteiro.fonte
Int
ou pode fazer com que essas coisas chamem essa função gratuita - o que seu coração desejar.Se você realmente deseja uma implementação 'Int only' e não quer forçar de / para
Double
, você precisará implementá-la. Aqui está uma implementação trivial; existem algoritmos mais rápidos, mas isso funcionará:Em uma implementação real, você provavelmente deseja alguma verificação de erros.
fonte
Double(Int.max - 1) < Double(Int.max)
em um REPL Swift 3 e você ficará surpreso.reduce
chamada.return (2...power).reduce(base) { result, _ in result * base }
pequeno detalhe mais
swift - Expressões binárias
fonte
Se você não está inclinado a sobrecarregar o operador (embora a
^^
solução provavelmente seja clara para alguém que está lendo seu código), você pode fazer uma implementação rápida:fonte
mklbtz está correto sobre a exponenciação por quadrado ser o algoritmo padrão para calcular potências inteiras, mas a implementação recursiva de cauda do algoritmo parece um pouco confusa. Veja http://www.programminglogic.com/fast-exponentiation-algorithms/ para uma implementação não recursiva de exponenciação por quadrado em C. Eu tentei traduzi-lo para Swift aqui:
Claro, isso poderia ser imaginado criando um operador sobrecarregado para chamá-lo e poderia ser reescrito para torná-lo mais genérico para que funcionasse em qualquer coisa que implementasse o
IntegerType
protocolo. Para torná-lo genérico, provavelmente começaria com algo comoMas, isso provavelmente está se deixando levar.
fonte
BinaryInteger
.IntegerType
foi descontinuado.Ou apenas :
fonte
Combinar as respostas em um conjunto sobrecarregado de funções (e usar "**" em vez de "^^" como algumas outras linguagens usam - mais claro para mim):
Ao usar Float, você pode perder a precisão. Se estiver usando literais numéricos e uma mistura de inteiros e não inteiros, você terminará com Double por padrão. Pessoalmente, gosto da capacidade de usar uma expressão matemática em vez de uma função como pow (a, b) por motivos estilísticos / legibilidade, mas sou só eu.
Quaisquer operadores que façam pow () lançar um erro também farão com que essas funções gerem um erro, portanto, o fardo da verificação de erros ainda recai sobre o código que usa a função power de qualquer maneira. KISS, IMHO.
Usar a função nativa pow () permite, por exemplo, obter raízes quadradas (2 ** 0,5) ou inversa (2 ** -3 = 1/8). Por causa da possibilidade de usar expoentes inversos ou fracionários, escrevi todo o meu código para retornar o tipo Double padrão da função pow (), que deve retornar a maior precisão (se bem me lembro da documentação). Se necessário, isso pode ser convertido em tipo para Int ou Float ou qualquer outro, possivelmente com perda de precisão.
fonte
Acontece que você também pode usar
pow()
. Por exemplo, você pode usar o seguinte para expressar 10 à 9ª.Junto com
pow
,powf()
retorna um emfloat
vez de adouble
. Eu testei isso apenas no Swift 4 e no macOS 10.13.fonte
Para calcular
power(2, n)
, basta usar:fonte
Versão Swift 4.x
fonte
Em Swift 5:
Usar assim
Obrigado a resposta de @Paul Buis.
fonte
Array (repetindo: a, contagem: b) .reduce (1, *)
fonte
Uma função de potência baseada em Int que calcula o valor diretamente por meio do deslocamento de bits para a base 2 no Swift 5:
(Certifique-se de que o resultado está dentro do intervalo de Int - isso não verifica o caso fora dos limites)
fonte
As outras respostas são ótimas, mas se preferir, você também pode fazer isso com uma
Int
extensão, desde que o expoente seja positivo.fonte
Tentando combinar a sobrecarga, tentei usar genéricos, mas não consegui fazer funcionar. Finalmente decidi usar o NSNumber em vez de tentar sobrecarregar ou usar genéricos. Isso simplifica o seguinte:
O código a seguir tem a mesma função acima, mas implementa a verificação de erros para ver se os parâmetros podem ser convertidos para Doubles com êxito.
fonte
Swift 5
Fiquei surpreso, mas não encontrei uma solução correta adequada aqui.
Isso é meu:
Exemplo:
fonte
Eu gosto mais disso
fonte
Exemplo:
fonte