Skip to content

Instantly share code, notes, and snippets.

@jmalarcon
Created November 25, 2022 09:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmalarcon/ac5315f156ed7dbb683332ac0818a079 to your computer and use it in GitHub Desktop.
Save jmalarcon/ac5315f156ed7dbb683332ac0818a079 to your computer and use it in GitHub Desktop.
¿Dónde está el código fuente de Math.Pow en .NET?

¿Dónde puedo encontrar el código fuente del método Pow() de la clase Math de .NET?

Respuesta a la pregunta de Jesús Santos en este vídeo mío en YouTube

image

En primer lugar, esto no es algo de C#, como planteas en tu pregunta, sino algo perteneciente a .NET, y por lo tanto disponible en todos los lenguajes que funcionan sobre la plataforma.

Lo primero es encontrar el método que te interesa, y por lo tanto la clase que lo implementa.

Math es una clase básica de .NET que se encuentra en el espacio de nombres por defecto, o sea, en System. Si lo buscas en ILSpy (que es lo que utilizo en el vídeo para descompilar aplicaciones .NET) lo tendrás que buscar en el ensamblado System.Private.CoreLib.dll, pero no es necesario saberlo ya que basta con usar la búsqueda del programa con la palabra "Math" para encontrarlo de primero:

image

Ahí verás su código directamente:

image

que no te dirá gran cosa.

Si lo buscas en GitHub debes localizarlo en el repositorio dotnet/runtime, que es el que contiene el código fuente del runtime de .NET. Basta con usar la búsqueda de GitHub para encontrarte la clase:

image

y dentro de esta buscas [el método que te interesa](Uploading image.png…. Verás que es exactamente lo mismo que sacas de ILSpy:

image

Como ves, no te dice gran cosa. El motivo es que este método está implementado de manera nativa por .NET, es decir, no utiliza C# o ningún otro lenguaje de .NET sino que se aprovecha de las instrucciones nativas de los procesadores para hacer ese cálculo, lo cual tiene toda la lógica del mundo. De todos modos vamos a seguir tirando del hilo...

Los atributos que tiene son:

  • [Intrinsic](https://github.com/dotnet/runtime/issues/23057): es un método que se utiliza en principio solo para el desarrollo interno de .NET y que marca los métodos como optimizables por el compilador Just In Time (JIT) o que se ha implementado por la máquina virtual de ejecución de .NET para mapearlo/asociarlo a un código nativo.
  • MethodImpl(MethodImplOptions.InternalCall): indica que este método ha sido implementado internamente por el CLR (Common Language Runtime).

Es decir, nos confirman que este método, al igual que la mayoría de la clase Math se han implementado directamente en código nativo, para lo cual se suele utilizar los lenguajes C o C++.

Estos métodos están almacenados en diversos sitios del código fuente del runtime de .NET. Hay una carpeta native dentro de src que promete, pero en realidad, si buscas algún archivo llamado math verás que está realmente en /src/coreclr/pal/src/cruntime/math.cpp:

image

¡Ahí lo tenemos! Es un archivo C++.

Nota: eso de "pal" viene de Platform Adaptation Layer o capa de adaptación a la plataforma.

Si vas a ese archivo y buscas Pow te llevará a su código fuente nativo.

Básicamente lo que hace es utilizar la función pow de C++ o recurrir a otras operaciones en caso de que la plataforma no tenga una imnplementación específica.

Dado que el runtime de .NET se compila para cada plataforma independientemente, generará el código nativo necesario para cada una.

Así que si lo que buscabas era cómo se calcula directamente con código C# la potencia de un número, me temo que no lo vas a encontrar en su código fuente, al igual que no enocntrarás cómo se realiza la operación de suma o de resta, que recurre a código de bajo nivel, más eficiente, para hacerlo.

Puedes echar un vistazo a cómo se hace con números grandes (con la clase BigInteger) pero no sé si será tampoco nada esclarecedor para lo que buscas.

@jesus-santos02
Copy link

Hola, hice la búsqueda en github que planteaste y me arrojó el siguiente resultado, alguna idea de por qué no se parece al de tu imagen?:

image

Incluso le di al apartado donde dice "Code" y este fue el resultado:

image

@jmalarcon
Copy link
Author

No sé qué te puede estar pasando, porque funcionar funciona. Quizá algo mal escrito o un espacio de más o de menos en algún lado... Pero es muy fácil de solucionar: simplemente entra en el repositorio dotnet/runtime y, una vez en él, vete a la caja de búsqueda. Ya te deja seleccionado el propio repo y solo tienes que buscar en él:

busacr-en-repo

Y como ves da el resultado esperado.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment