/************************************************************* ************************************************************* * ROUNDED TOWARD +INFINITY * ************************************************************* *************************************************************/ double scs_cos_ru(double x){ scs_t sc1, sc2; double resd; int N; #if EVAL_PERF crlibm_second_step_taken++; #endif scs_set_d(sc1, x); N = rem_pio2_scs(sc2, sc1); N = N & 0x0000003; /* extract the 2 last bits of N */ switch (N){ case 0: cosine(sc2); scs_get_d_pinf(&resd, sc2); return resd; break; case 1: sine(sc2); /* Change rounding mode */ scs_get_d_minf(&resd, sc2); return -resd; case 2: cosine(sc2); /* Change rounding mode */ scs_get_d_minf(&resd, sc2); return -resd; case 3: sine(sc2); scs_get_d_pinf(&resd, sc2); return resd; default: fprintf(stderr,"ERREUR: %d is not a valid value in s_cos \n", N); exit(1); } return resd; }
double scs_atanpi_ru(double x){ scs_t sc1; scs_t res_scs; db_number res; int sign = 1; res.d = x; /* Filter cases */ if (x < 0){ sign = -1; x *= -1; } scs_set_d(sc1, x); scs_atanpi(res_scs, sc1); if (sign == -1){ scs_get_d_minf(&res.d, res_scs); res.d *= -1; return res.d; } else{ scs_get_d_pinf(&res.d, res_scs); return res.d; } }
double scs_tan_rd(double x){ scs_t res_scs; double resd; #if EVAL_PERF crlibm_second_step_taken++; #endif scs_tan(x,res_scs); scs_get_d_minf(&resd, res_scs); return resd; }
/************************************************************* ************************************************************* * ROUNDED TOWARD -INFINITY ************************************************************* *************************************************************/ double log10_rd(double x) { scs_t R, res1; scs_t sc_ln2_r10_times_E; scs_ptr inv_wi, ti; db_number nb, nb2, wi, resd; int i, E=0; nb.d = x; /* Filter cases */ if (nb.i[HI_ENDIAN] < 0x00100000){ /* x < 2^(-1022) */ if (((nb.i[HI_ENDIAN] & 0x7fffffff)|nb.i[LO_ENDIAN])==0) /* return 1.0/0.0; */ /* log(+/-0) = -Inf */ return NInf.d; if (nb.i[HI_ENDIAN] < 0) /* return (x-x)/0; */ /* log(-x) = Nan */ return NaN.d; /* Subnormal number */ E -= (SCS_NB_BITS*2); /* keep in mind that x is a subnormal number */ nb.d *=SCS_RADIX_TWO_DOUBLE; /* make x as normal number */ /* We may just want add 2 to the scs number.index */ /* may be .... we will see */ } if (nb.i[HI_ENDIAN] >= 0x7ff00000) return x+x; /* Inf or Nan */ /* find n, nb.d such that sqrt(2)/2 < nb.d < sqrt(2) */ E += (nb.i[HI_ENDIAN]>>20)-1023; nb.i[HI_ENDIAN] = (nb.i[HI_ENDIAN] & 0x000fffff) | 0x3ff00000; if (nb.d > SQRT_2){ nb.d *= 0.5; E++; } /* to normalize nb.d and round to nearest */ /* +((2^4 - trunc(sqrt(2)/2) *2^4 )*2 + 1)/2^5 */ nb2.d = nb.d + norm_number.d; i = (nb2.i[HI_ENDIAN] & 0x000fffff); i = i >> 16; /* 0<= i <=11 */ wi.d = (11+i)*(double)0.6250e-1; /* (1+f-w_i) */ nb.d -= wi.d; /* Table reduction */ ti = table_ti_ptr[i]; inv_wi = table_inv_wi_ptr[i]; /* R = (1+f-w_i)/w_i */ scs_set_d(R, nb.d); scs_mul(R, R, inv_wi); /* sc_ln2_r10_times_E = E*log10(2) */ scs_set(sc_ln2_r10_times_E, sc_ln2_r10_ptr); if (E >= 0){ scs_mul_ui(sc_ln2_r10_times_E, (unsigned int) E); }else{ scs_mul_ui(sc_ln2_r10_times_E, (unsigned int) -E); sc_ln2_r10_times_E->sign = -1; } /* * Polynomial evaluation of log10(1 + R) with an error less than 2^(-130) */ scs_mul(res1, constant_poly_ptr[0], R); for(i=1; i<20; i++){ scs_add(res1, constant_poly_ptr[i], res1); scs_mul(res1, res1, R); } scs_add(res1, res1, ti); scs_add(res1, res1, sc_ln2_r10_times_E); scs_get_d_minf(&resd.d, res1); return resd.d; }