Saltar al contenido principal
LibreTexts Español

9.2: “Sí, me gustaría una mesa para 360, por favor”

  • Page ID
    81966
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    Considera la función común del trigo C, sin (). No mucho a eso, en serio. Le pasas una discusión y recuperas el seno del argumento. Pero, ¿cómo se implementa? Podría implementarse como una expansión de la Serie Taylor que requiere varias multiplica y agrega. Un cómputo de seno único no tardará mucho pero ¿y si necesitas hacer millones de ellos? Todos esos se multiplican y suman, por así decirlo. Considera el siguiente problema: Necesitas obtener el seno de un ángulo especificado al grado más cercano, y rápido. Básicamente, tienes 360 respuestas posibles (0 grados a 359 grados) 1. Ahora supongamos que crea una matriz de 360 valores que consiste en el seno de cada ángulo en incrementos de un grado, comenzando en 0 grados y trabajando hasta 359 grados. Podría verse algo como esto:

    double sine_table[] = { 0.0, 0.01745, 0.034899, 0.05234,
        /* and so on to the last entry */ -0.01745 };
    

    Ahora puedes “computar” el seno así, dado el argumento ángulo:

    answer = sine_table[ angle ];
    

    Debido a la dualidad de matrices y punteros, también puede escribir esto como:

    answer = *(sine_table + angle);
    

    Sin un compilador de optimización, la segunda forma probablemente generará código de máquina más eficiente. En cualquier caso, esto es muy rápido porque no es más que leer desde una ubicación de memoria con un desplazamiento. El resultado es solo un agregado más el acceso en lugar de una docena de multiplicar/agregar. Viene a costa de 360 flotadores dobles, que, a ocho bytes cada uno, es casi 3k de memoria. Al reconocer que la función sinusoidal tiene simetría de cuarto de onda, puede agregar un poco de código para verificar el cuadrante y reducir la tabla a solo 90 entradas. Además, los flotadores podrían tener suficiente precisión para la aplicación, lo que reducirá los requisitos de memoria a la mitad nuevamente en comparación con el doble s.

    Para hacer lo anterior un poco más spiffier, siempre puedes hacer que parezca una función a través de un #define de la siguiente manera:

    #define fast_sin(a)  (*(sine_table+(a)))
    

    Por supuesto, un inconveniente de esta operación es que solo trata con un argumento entero y solo es precisa en un solo grado. Puede alterar la definición para permitir un argumento de punto flotante y redondearlo al grado completo más cercano de la siguiente manera:

    #define fast_sin(a) (*(sine_table+(int)((a)+0.5)))
    

    También podría convertir esto en una función verdadera y agregar código para interpolar entre entradas de grados enteros adyacentes para obtener un resultado más preciso. En algún momento los refinamientos adicionales ralentizarán la función hasta el punto en que un cálculo más directo se vuelva competitivo.


    1. Fuera de esos límites siempre puedes realizar algunas matemáticas de enteros menores para meterte dentro de los límites (por ejemplo, si el ángulo es 370, solo mod por 360 para obtener el resto de 10 grados, efectivamente el “wrap around”).

    This page titled 9.2: “Sí, me gustaría una mesa para 360, por favor” is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by James M. Fiore via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.