/*
 * test_sincos.c
 *
 * Test stand-alone glibc sin and cos functions,
 * with proper range reduction.
 *
 * K. Myneni
 * 3 Sep 2026
 *
 * Requires:
 *   branred.o
 *   s_sin.o
 *   sincostab.o
*/

#include <stdio.h>
#include <math.h>
#include <fenv.h>
#include <fpu_control.h>

extern double g_sin(double);
extern double g_cos(double);

#define LO_32( x ) (*((unsigned long int*) &x))
#define HI_32( x ) (*(((unsigned long int*) &x + 1)))

int main()
{
    double x, c, s;
    unsigned long int c_lo32, c_hi32, s_lo32, s_hi32;
    unsigned short int cw_old, cw;

    // set fpu precision and rounding mode for compatibility
    // with double-double arithmetic
    _FPU_GETCW(cw);
    cw_old = cw;
    cw = cw & 0xf0ff;
    cw = cw | 0x200;
    _FPU_SETCW(cw);

    while (1) {
      printf("\n\nEnter a real: ");
      scanf("%lf", &x);
      c = g_cos(x);
      s = g_sin(x);
      c_lo32 = LO_32( c );
      c_hi32 = HI_32( c );
      s_lo32 = LO_32( s );
      s_hi32 = HI_32( s );

      printf("\nsin(x) = %.18e  %08x  %08x",   s, s_lo32, s_hi32);
      printf("\ncos(x) = %.18e  %08x  %08x\n", c, c_lo32, c_hi32);
    }
    return 0;
}


