Estoy aprendiendo rápido recientemente, pero tengo un problema básico que no puedo encontrar una respuesta.
Quiero conseguir algo como
var a:Int = 3
var b:Int = 3
println( pow(a,b) ) // 27
pero la función pow puede funcionar solo con un número doble, no funciona con un número entero, y ni siquiera puedo convertir el int para doblar con algo como Double (a) o a.double () ...
¿Por qué no proporciona el poder del número entero? ¡definitivamente devolverá un número entero sin ambigüedad! y ¿Por qué no puedo convertir un número entero en un doble? simplemente cambia 3 a 3.0 (o 3.00000 ... lo que sea)
si tengo dos enteros y quiero hacer la operación de energía, ¿cómo puedo hacerlo sin problemas?
¡Gracias!
Respuestas:
Si lo desea, puede declarar un
infix
operator
para hacerlo.Usé dos signos de intercalación para que puedas seguir usando el operador XOR .
Actualización para Swift 3
En Swift 3, el "número mágico"
precedence
se reemplaza porprecedencegroups
:fuente
infix operator ^^ { precedence 160 } func ^^
... y así sucesivamentefunc p(_ b: Bool) -> Double { return b?-1:1 }
?Aparte de que sus declaraciones de variables tienen errores de sintaxis, esto funciona exactamente como esperaba. Todo lo que tienes que hacer es lanzar
a
yb
duplicar y pasar los valores apow
. Luego, si está trabajando con 2 Ints y quiere un Int de vuelta en el otro lado de la operación, simplemente devuelva a Int.fuente
3 ** 3
. A veces, necesito resolver un problema de algoritmo usando Swift, es realmente doloroso en comparación con el uso de Python.A veces, lanzar un
Int
to aDouble
no es una solución viable. En algunas magnitudes hay una pérdida de precisión en esta conversión. Por ejemplo, el siguiente código no devuelve lo que podría esperar intuitivamente.Si necesita precisión en magnitudes altas y no necesita preocuparse por exponentes negativos , que generalmente no se pueden resolver con números enteros de todos modos, entonces esta implementación del algoritmo de exponenciación por cuadratura recursiva de cola es su mejor opción. Según esta respuesta SO , este es "el método estándar para hacer exponenciación modular para grandes números en criptografía asimétrica".
Nota: en este ejemplo he usado un archivo
T: BinaryInteger
. Esto es lo que puede utilizarInt
oUInt
, o cualquier otro tipo entero similar.fuente
Int
o puede hacer que esas cosas llamen a esta función gratuita, lo que su corazón desee.Si realmente desea una implementación 'Int solo' y no desea forzar a / desde
Double
, deberá implementarla. Aquí hay una implementación trivial; hay algoritmos más rápidos pero esto funcionará:En una implementación real, probablemente querrá verificar algunos errores.
fuente
Double(Int.max - 1) < Double(Int.max)
Swift 3 REPL y se sorprenderá.reduce
llamada.return (2...power).reduce(base) { result, _ in result * base }
pequeño detalle más
swift - Expresiones binarias
fuente
Si no está inclinado a la sobrecarga de operadores (aunque la
^^
solución probablemente sea clara para alguien que lea su código), puede hacer una implementación rápida:fuente
mklbtz tiene razón acerca de la exponenciación al elevar al cuadrado como algoritmo estándar para calcular potencias enteras, pero la implementación recursiva de cola del algoritmo parece un poco confusa. Consulte http://www.programminglogic.com/fast-exponentiation-algorithms/ para ver una implementación no recursiva de exponenciación al elevar al cuadrado C. Intenté traducirlo a Swift aquí:
Por supuesto, esto podría inventarse creando un operador sobrecargado para llamarlo y podría reescribirse para hacerlo más genérico para que funcione en cualquier cosa que implemente el
IntegerType
protocolo. Para hacerlo genérico, probablemente comenzaría con algo comoPero, eso probablemente se esté dejando llevar.
fuente
BinaryInteger
.IntegerType
estaba en desuso.O solo :
fuente
Combinando las respuestas en un conjunto de funciones sobrecargadas (y usando "**" en lugar de "^^" como usan otros idiomas, más claro para mí):
Al usar Float, puede perder precisión. Si usa literales numéricos y una combinación de enteros y no enteros, terminará con Double por defecto. Personalmente, me gusta la capacidad de usar una expresión matemática en lugar de una función como pow (a, b) por razones de estilo / legibilidad, pero así soy yo.
Cualquier operador que cause que pow () arroje un error también hará que estas funciones arrojen un error, por lo que la carga de la verificación de errores aún recae en el código que usa la función power de todos modos. BESO, en mi humilde opinión.
El uso de la función nativa pow () permite, por ejemplo, tomar raíces cuadradas (2 ** 0.5) o inversas (2 ** -3 = 1/8). Debido a la posibilidad de usar exponentes inversos o fraccionarios, escribí todo mi código para devolver el tipo Double predeterminado de la función pow (), que debería devolver la mayor precisión (si recuerdo la documentación correctamente). Si es necesario, esto se puede convertir en Int o Float o lo que sea, posiblemente con la pérdida de precisión.
fuente
Resulta que también puedes usar
pow()
. Por ejemplo, puede usar lo siguiente para expresar 10 al noveno.Junto con
pow
,powf()
devuelve a enfloat
lugar de adouble
. Solo lo he probado en Swift 4 y macOS 10.13.fuente
Para calcular
power(2, n)
, simplemente use:fuente
Versión Swift 4.x
fuente
En Swift 5:
Úselo así
Gracias a la respuesta de @Paul Buis.
fuente
Array (repitiendo: a, cuenta: b) .reduce (1, *)
fuente
Una función de pow basada en Int que calcula el valor directamente a través del desplazamiento de bits para la base 2 en Swift 5:
(Asegúrese de que el resultado esté dentro del rango de Int; esto no verifica el caso fuera de límites)
fuente
Las otras respuestas son excelentes, pero si lo prefiere, también puede hacerlo con una
Int
extensión siempre que el exponente sea positivo.fuente
Intentando combinar la sobrecarga, intenté usar genéricos pero no pude hacerlo funcionar. Finalmente pensé en usar NSNumber en lugar de intentar sobrecargar o usar genéricos. Esto se simplifica a lo siguiente:
El siguiente código es la misma función que el anterior, pero implementa la verificación de errores para ver si los parámetros se pueden convertir a dobles con éxito.
fuente
Rápido 5
Me sorprendió, pero no encontré una solución correcta y adecuada aquí.
Esto es mío:
Ejemplo:
fuente
Me gusta mas esto
fuente
Ejemplo:
fuente