Si bien existe dicho operador, **
en Python, me preguntaba por qué Java y C ++ tampoco tienen uno.
Es fácil crear uno para las clases que defina en C ++ con sobrecarga del operador (y creo que esto también es posible en Java), pero cuando se habla de tipos primitivos como int, double, etc., deberá usar la biblioteca funcionan como Math.power
(y generalmente tienen que lanzar ambos al doble).
Entonces, ¿por qué no definir dicho operador para los tipos primitivos?
^
operador no coincide con la precedencia de la exponenciación. Considera la expresióna + b ^ c
. En matemáticas, la exponenciación se realiza primero (b ^ c
), luego se agrega la potencia resultantea
. En C ++, la adición se realiza primero (a + b
) y luego^
se realiza el operador conc
. Entonces, incluso si implementó el^
operador para significar exponenciación, la precedencia sorprenderá a todos.^
es un XOR en C ++. Se recomienda que el operador sobrecargado no haga diferente lo que hace un tipo de datos primitivo al usarlo.++
operador o al!
operador et. Alabama. significar exponenciación. Pero de todos modos no puedes, porque los operadores de los que hablas aceptan solo un argumento; La exponenciación requiere dos argumentos.Respuestas:
En términos generales, los operadores primitivos en C (y por extensión C ++) están diseñados para ser implementados por hardware simple en aproximadamente una sola instrucción. Algo como la exponenciación a menudo requiere soporte de software; entonces no está allí por defecto.
Además, es proporcionado por la biblioteca estándar del idioma en forma de
std::pow
.Finalmente, hacer esto para los tipos de datos enteros no tendría mucho sentido, porque la mayoría de los valores incluso pequeños para la exponenciación superan el rango requerido para int, que es hasta 65.535. Claro, podrías hacer esto para dobles y flotantes, pero no para ints, pero ¿por qué hacer que el lenguaje sea inconsistente para una característica raramente utilizada?
fuente
DIV
hace división y módulo) Sin embargo, me tienes en el punto de consistencia.div
o con FORTRAN.EQ.
); Dependiendo de las reglas del espacio en blanco del lenguaje, puede ser posible tener un número arbitrario de operadores sin requerir que sean palabras reservadas.Esta pregunta es responsable de C ++: Stroustrup, "Diseño y evolución de C ++", trata esto en la sección 11.6.1, pp. 247-250.
Hubo objeciones generales para agregar un nuevo operador. Se agregaría a la tabla de precedencia ya demasiado complicada. Los miembros del grupo de trabajo pensaron que sería muy conveniente tener una función, y en ocasiones querían poder sustituir sus propias funciones.
No había un buen candidato para un operador.
^
es exclusivo-o, e^^
invita a la confusión debido a la relación entre&
y|
y&&
y||
.!
no era adecuado, ya que habría una tendencia natural a escribir!=
para la exponenciación de un valor existente, y eso ya se había tomado. El mejor disponible puede haber sido*^
, que aparentemente a nadie le gustó realmente.Stroustrup lo consideró
**
nuevamente, pero ya tiene un significado en C:a**p
esa
veces lo que sea quep
apunte, y sechar ** c;
declarac
como un puntero a apuntarchar
. La introducción**
como un token que significa "declaración de un puntero a puntero a", "multiplicado por lo que señala lo siguiente" (si es un puntero) o "exponenciación" (si va seguido de un número) causó problemas de precedencia.a/b**p
tendría que analizar comoa/(b**p)
si p fuera un número, pero(a/b) * *p
si p fuera un puntero, entonces esto debería resolverse en el analizador.En otras palabras, habría sido posible, pero habría complicado la tabla de precedencia y el analizador, y ambos ya son demasiado complicados.
No sé la historia sobre Java; todo lo que podría hacer sería especular. En cuanto a C, donde comenzó, todos los operadores de C se traducen fácilmente en código de ensamblaje, en parte para simplificar el compilador y en parte para evitar ocultar la funcionalidad que consume mucho tiempo en operadores simples (el hecho de que
operator+()
y otros pudieran ocultar una gran complejidad y golpes de rendimiento fue uno de las primeras quejas sobre C ++).fuente
*^
. : Da**p
es el asesino. (Los trucos para solucionar ese problema ... ¡Brr!)Yo sospecho que es porque todos los operadores se introduce aumenta la complejidad de la lengua. La barrera de entrada es, por lo tanto, muy alta. Me encuentro usando la exponenciación muy, muy raramente, y estoy más que feliz de usar una llamada de método para hacerlo.
fuente
x**2
yx**3
no tan raramente. Y una implementación de pow mágico que el compilador conoce y optimiza para los casos simples estaría bien.x * x
, yx * x * x
no son malos sustitutos del cuadrado y el cubo.x*x
si x es una expresión. En el mejor de los casos, el código se vuelve difícil de manejar y, en el peor, más lento o incluso incorrecto. Por lo tanto, necesitaría definir sus propias funciones Square y Cube. E incluso entonces el código sería más feo que usar ** como operador de energía.El lenguaje Java y los diseñadores de la biblioteca central decidieron relegar la mayoría de las operaciones matemáticas a la clase de Matemáticas . Ver Math.pow () .
¿Por qué? Flexibilidad para priorizar el rendimiento sobre la precisión bit por bit. Iría en contra del resto de las especificaciones del lenguaje decir que el comportamiento de los operadores matemáticos incorporados podría variar de una plataforma a otra, mientras que la clase de Matemáticas establece específicamente que el comportamiento potencialmente sacrifica la precisión por el rendimiento, por lo que el comprador tenga cuidado:
fuente
La exponenciación fue parte de Fortran desde el principio porque estaba dirigida directamente a la programación científica. Los ingenieros y físicos lo usan a menudo en simulaciones, porque las relaciones de la ley de poder son comunes en la física.
Python también tiene una fuerte presencia en informática científica (por ejemplo, NumPy y SciPy). Eso, junto con su operador de exponenciación, sugiere que también estaba dirigido a la programación científica.
C, Java y C # tienen raíces en la programación del sistema. Quizás esa sea una influencia que mantuvo la exponenciación fuera del grupo de operadores compatibles.
Solo una teoria.
fuente
C solo definió operadores para operaciones aritméticas comunes accesibles con la ALU. Su objetivo principal era crear una interfaz legible por humanos para el código de ensamblaje.
C ++ no cambió el comportamiento de ningún operador porque quería que toda la base de código escrita en C fuera compatible.
Java hizo lo mismo porque no quería intimidar a los programadores de C ++ existentes.
fuente
Bueno, porque cada operador que tendría sentido para una potencia ya está en uso. ^ es XOR y ** define un puntero a un puntero. Entonces, en cambio, solo tienen una función que hace lo mismo. (como pow ())
fuente
pow()
función realiza su cálculo en tiempo de ejecución, a menos que tenga un compilador que pueda hacer un plegado constantepow()
, lo cual dudo mucho. (Algunos compiladores le dan la opción de utilizar las características intrínsecas del procesador para realizar el cálculo, sin embargo.)*
es un token léxico, ya sea que se use para indirección o multiplicación. Una**
exponenciación de significado sería uno o dos tokens léxicos, y realmente no desea que su lexer tenga que presionar la tabla de símbolos para tokenizar.El hecho es que los operadores aritméticos son solo atajos de funciones. (Casi) Todo lo que haces con ellos se puede hacer con una función. Ejemplo:
Es simplemente más detallado, por lo que no veo nada de malo en usar funciones para realizar 'poder de'.
fuente
Suma / resta / negación y multiplicación / división son operadores matemáticos básicos. Si tuvieras que hacer del poder un operador, ¿dónde te detendrías? Operador de raíz cuadrada? Operador de raíz N? Operador de logaritmo?
No puedo hablar por sus creadores, pero puedo decir que creo que sería difícil de manejar y no ortogonal tener tales operadores en el idioma. El número de caracteres no alfanuméricos / en blanco que quedan en el teclado es bastante limitado. Tal como están las cosas, es extraño que haya un operador de módulo en C ++.
fuente
mod
es extraño tener como operador. Suele ser una sola instrucción. Es una operación primitiva en enteros. Se usa en casi todas partes en informática. (Implementar cosas como amortiguadores limitados sinmod