Beispiel #1
0
 inline IFloat e() const
 {
     return IFloat(-(Float)(-exp_rd(1)), exp_ru(1));
 }
Beispiel #2
0
interval j_exp(interval x)
{
  interval res;
  double x_inf, x_sup;
  double rh_sup, rm_sup, rl_sup, tbl1h_sup, tbl1m_sup, tbl1l_sup;
  double tbl2h_sup, tbl2m_sup, tbl2l_sup;
  double xMultLog2InvMult2L_sup, shiftedXMult_sup, kd_sup;
  double msLog2Div2LMultKh_sup, msLog2Div2LMultKm_sup, msLog2Div2LMultKl_sup;
  double t1_sup, t2_sup, polyTblh_sup, polyTblm_sup, polyTbll_sup;
  db_number shiftedXMultdb_sup, xdb_sup, resdb_sup;
  int k_sup, M_sup, index1_sup, index2_sup, xIntHi_sup, mightBeDenorm_sup, roundable;
  double t8_sup, t9_sup, t10_sup, t11_sup, t12_sup, t13_sup;
  double rhSquare_sup, rhSquareHalf_sup, rhC3_sup, rhFour_sup, monomialCube_sup;
  double highPoly_sup, highPolyWithSquare_sup, monomialFour_sup;
  double tablesh_sup, tablesl_sup;
  double s1_sup, s2_sup, s3_sup, s4_sup, s5_sup;
  double res_sup;

  double rh_inf, rm_inf, rl_inf, tbl1h_inf, tbl1m_inf, tbl1l_inf;
  double tbl2h_inf, tbl2m_inf, tbl2l_inf;
  double xMultLog2InvMult2L_inf, shiftedXMult_inf, kd_inf;
  double msLog2Div2LMultKh_inf, msLog2Div2LMultKm_inf, msLog2Div2LMultKl_inf;
  double t1_inf, t2_inf, polyTblh_inf, polyTblm_inf, polyTbll_inf;
  db_number shiftedXMultdb_inf, xdb_inf, resdb_inf;
  int k_inf, M_inf, index1_inf, index2_inf, xIntHi_inf, mightBeDenorm_inf;
  double t8_inf, t9_inf, t10_inf, t11_inf, t12_inf, t13_inf;
  double rhSquare_inf, rhSquareHalf_inf, rhC3_inf, rhFour_inf, monomialCube_inf;
  double highPoly_inf, highPolyWithSquare_inf, monomialFour_inf;
  double tablesh_inf, tablesl_inf;
  double s1_inf, s2_inf, s3_inf, s4_inf, s5_inf;
  double res_inf;

  double res_simple_inf, res_simple_sup;
  int infDone=0; int supDone=0;

  x_inf=LOW(x);
  x_sup=UP(x);

  /* Argument reduction and filtering for special cases */

  /* Compute k as a double and as an int */
  xdb_sup.d = x_sup;
  xdb_inf.d = x_inf;
  xMultLog2InvMult2L_sup = x_sup * log2InvMult2L;
  xMultLog2InvMult2L_inf = x_inf * log2InvMult2L;
  shiftedXMult_sup = xMultLog2InvMult2L_sup + shiftConst;
  shiftedXMult_inf = xMultLog2InvMult2L_inf + shiftConst;
  kd_sup = shiftedXMult_sup - shiftConst;
  kd_inf = shiftedXMult_inf - shiftConst;
  shiftedXMultdb_sup.d = shiftedXMult_sup;
  shiftedXMultdb_inf.d = shiftedXMult_inf;


  /* Special cases tests */
  xIntHi_sup = xdb_sup.i[HI];
  mightBeDenorm_sup = 0;

  /* Special cases tests */
  xIntHi_inf = xdb_inf.i[HI];
  mightBeDenorm_inf = 0;

  if ( __builtin_expect(
       ((xIntHi_sup & 0x7ff00000) == 0)
    || (((xIntHi_sup & 0x7ff00000) == 0)  && (x_sup == 0.0)) 
    || (((xIntHi_sup & 0x7ff00000) == 0)  && (x_sup < 0.0))
    || (((xIntHi_sup & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && ((xIntHi_sup & 0x7fffffff) >= 0x7ff00000))
    || (((xIntHi_sup & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && ((xIntHi_sup & 0x7fffffff) >= 0x7ff00000) && (((xIntHi_sup & 0x000fffff) | xdb_sup.i[LO]) != 0))
    || (((xIntHi_sup & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && ((xIntHi_sup & 0x7fffffff) >= 0x7ff00000) && ((xIntHi_sup & 0x80000000)==0))
    || (((xIntHi_sup & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && (x_sup > OVRFLWBOUND))
    || (((xIntHi_sup & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && (x_sup <= UNDERFLWBOUND))
    || (((xIntHi_sup & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && (x_sup <= DENORMBOUND))
    || ((xIntHi_inf & 0x7ff00000) == 0)
    || (((xIntHi_inf & 0x7ff00000) == 0) && (x_inf == 0.0))
    || (((xIntHi_inf & 0x7ff00000) == 0) && (x_inf > 0.0))
    || (((xIntHi_inf & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && ((xIntHi_inf & 0x7fffffff) >= 0x7ff00000))
    || (((xIntHi_inf & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && ((xIntHi_inf & 0x7fffffff) >= 0x7ff00000) && (((xIntHi_inf & 0x000fffff) | xdb_inf.i[LO]) != 0))
    || (((xIntHi_inf & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && ((xIntHi_inf & 0x7fffffff) >= 0x7ff00000) && ((xIntHi_inf & 0x80000000)==0))
    || (((xIntHi_inf & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && (x_inf > OVRFLWBOUND))
    || (((xIntHi_inf & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && (x_inf <= UNDERFLWBOUND))
    || (((xIntHi_inf & 0x7fffffff) >= OVRUDRFLWSMPLBOUND) && (x_inf <= DENORMBOUND))
     ,FALSE))
  {
    ASSIGN_LOW(res,exp_rd(LOW(x)));
    ASSIGN_UP(res,exp_ru(UP(x)));
    return res;
  }

  /* Test if argument is a denormal or zero */
  /* If we are here, we are sure to be neither +/- Inf nor NaN nor overflowed nor denormalized in the argument
     but we might be denormalized in the result 

     We continue the argument reduction for the quick phase and table reads for both phases
  */

  Mul12(&s1_sup,&s2_sup,msLog2Div2Lh,kd_sup);
  Mul12(&s1_inf,&s2_inf,msLog2Div2Lh,kd_inf);
  s3_sup = kd_sup * msLog2Div2Lm;
  s3_inf = kd_inf * msLog2Div2Lm;
  s4_sup = s2_sup + s3_sup; 
  s4_inf = s2_inf + s3_inf; 
  s5_sup = x_sup + s1_sup;
  s5_inf = x_inf + s1_inf;
  Add12Cond(rh_sup,rm_sup,s5_sup,s4_sup);
  Add12Cond(rh_inf,rm_inf,s5_inf,s4_inf);
  k_sup = shiftedXMultdb_sup.i[LO];
  k_inf = shiftedXMultdb_inf.i[LO];
  M_sup = k_sup >> L;
  M_inf = k_inf >> L;
  index1_sup = k_sup & INDEXMASK1;
  index1_inf = k_inf & INDEXMASK1;
  index2_sup = (k_sup & INDEXMASK2) >> LHALF;
  index2_inf = (k_inf & INDEXMASK2) >> LHALF;

  /* Table reads */
  tbl1h_sup = twoPowerIndex1[index1_sup].hi;
  tbl1h_inf = twoPowerIndex1[index1_inf].hi;
  tbl1m_sup = twoPowerIndex1[index1_sup].mi;
  tbl1m_inf = twoPowerIndex1[index1_inf].mi;
  tbl2h_sup = twoPowerIndex2[index2_sup].hi;
  tbl2h_inf = twoPowerIndex2[index2_inf].hi;
  tbl2m_sup = twoPowerIndex2[index2_sup].mi;
  tbl2m_inf = twoPowerIndex2[index2_inf].mi;




  /* No more underflow nor denormal is possible. There may be the case where
     M is 1024 and the value 2^M is to be multiplied may be less than 1
     So the final result will be normalized and representable by the multiplication must be 
     made in 2 steps
  */

  /* Quick phase starts here */

  rhSquare_sup = rh_sup * rh_sup;
  rhSquare_inf = rh_inf * rh_inf;
  rhC3_sup = c3 * rh_sup;
  rhC3_inf = c3 * rh_inf;
  rhSquareHalf_sup = 0.5 * rhSquare_sup;
  rhSquareHalf_inf = 0.5 * rhSquare_inf;
  monomialCube_sup = rhC3_sup * rhSquare_sup;
  monomialCube_inf = rhC3_inf * rhSquare_inf;
  rhFour_sup = rhSquare_sup * rhSquare_sup;
  rhFour_inf = rhSquare_inf * rhSquare_inf;
  monomialFour_sup = c4 * rhFour_sup;
  monomialFour_inf = c4 * rhFour_inf;
  highPoly_sup = monomialCube_sup + monomialFour_sup;
  highPoly_inf = monomialCube_inf + monomialFour_inf;
  highPolyWithSquare_sup = rhSquareHalf_sup + highPoly_sup;
  highPolyWithSquare_inf = rhSquareHalf_inf + highPoly_inf;
  Mul22(&tablesh_sup,&tablesl_sup,tbl1h_sup,tbl1m_sup,tbl2h_sup,tbl2m_sup);
  Mul22(&tablesh_inf,&tablesl_inf,tbl1h_inf,tbl1m_inf,tbl2h_inf,tbl2m_inf);
  t8_sup = rm_sup + highPolyWithSquare_sup;
  t8_inf = rm_inf + highPolyWithSquare_inf;
  t9_sup = rh_sup + t8_sup;
  t9_inf = rh_inf + t8_inf;
  t10_sup = tablesh_sup * t9_sup;
  t10_inf = tablesh_inf * t9_inf;
  Add12(t11_sup,t12_sup,tablesh_sup,t10_sup);
  Add12(t11_inf,t12_inf,tablesh_inf,t10_inf);
  t13_sup = t12_sup + tablesl_sup;
  t13_inf = t12_inf + tablesl_inf;
  Add12(polyTblh_sup,polyTblm_sup,t11_sup,t13_sup);
  Add12(polyTblh_inf,polyTblm_inf,t11_inf,t13_inf);
  
  /* Rounding test 
     Since we know that the result of the final multiplication with 2^M 
     will always be representable, we can do the rounding test on the 
     factors and multiply only the final result.
     We implement the multiplication in integer computations to overcome
     the problem of the non-representability of 2^1024 if M = 1024
  */

  if (infDone==1) res_inf=res_simple_inf;
  if (supDone==1) res_sup=res_simple_sup;

//  TEST_AND_COPY_RDRU_EXP(roundable,infDone,supDone,res_inf,polyTblh_inf,polyTblm_inf,res_sup,polyTblh_sup,polyTblm_sup,RDROUNDCST);
  db_number yh_inf, yl_inf, u53_inf, yh_sup, yl_sup, u53_sup;
  int yh_inf_neg, yl_inf_neg, yh_sup_neg, yl_sup_neg;
  int rd_ok, ru_ok;
  double save_res_inf=res_inf;
  double save_res_sup=res_sup;
  yh_inf.d = polyTblh_inf;    yl_inf.d = polyTblm_inf;
  yh_inf_neg = (yh_inf.i[HI] & 0x80000000);
  yl_inf_neg = (yl_inf.i[HI] & 0x80000000);
  yh_inf.l = yh_inf.l & 0x7fffffffffffffffLL;  /* compute the absolute value*/
  yl_inf.l = yl_inf.l & 0x7fffffffffffffffLL;  /* compute the absolute value*/
  u53_inf.l     = (yh_inf.l & ULL(7ff0000000000000)) +  ULL(0010000000000000);
  yh_sup.d = polyTblh_sup;    yl_sup.d = polyTblm_sup;
  yh_sup_neg = (yh_sup.i[HI] & 0x80000000);
  yl_sup_neg = (yl_sup.i[HI] & 0x80000000);
  yh_sup.l = yh_sup.l & 0x7fffffffffffffffLL;  /* compute the absolute value*/
  yl_sup.l = yl_sup.l & 0x7fffffffffffffffLL;  /* compute the absolute value*/
  u53_sup.l     = (yh_sup.l & ULL(7ff0000000000000)) +  ULL(0010000000000000);
  roundable = 0;
  rd_ok=(yl_inf.d > RDROUNDCST * u53_inf.d);
  ru_ok=(yl_sup.d > RDROUNDCST * u53_sup.d);
     if(yl_inf_neg) {  /* The case yl==0 is filtered by the above test*/
      /* return next down */
       yh_inf.d = polyTblh_inf;
      if(yh_inf_neg) yh_inf.l++;  else yh_inf.l--; /* Beware: fails for zero */
      res_inf = yh_inf.d;
    }
    else {
      res_inf = polyTblh_inf;
    }
    if(!yl_sup_neg) {  /* The case yl==0 is filtered by the above test*/
      /* return next up */
      yh_sup.d = polyTblh_sup;
      if(yh_sup_neg) yh_sup.l--;  else yh_sup.l++; /* Beware: fails for zero */
      res_sup = yh_sup.d;
    }
    else {
      res_sup = polyTblh_sup;
    }
  if(infDone) res_inf=save_res_inf;
  if(supDone) res_sup=save_res_sup;
  if(rd_ok && ru_ok){
    roundable=3;
  }
  else if (rd_ok){
    roundable=1;
  }
  else if (ru_ok){
     roundable=2;
  }
  resdb_inf.d = res_inf;
  resdb_sup.d = res_sup;

  if (roundable==3)
  {
    if (infDone==0){
      resdb_inf.i[HI] += M_inf << 20;
    }
    ASSIGN_LOW(res,resdb_inf.d);
    if (supDone==0){
      resdb_sup.i[HI] += M_sup << 20;
    }
    ASSIGN_UP(res,resdb_sup.d);
    return res;
  }
  if(roundable==1)
  {
    if(infDone==0){
      resdb_inf.i[HI] += M_inf << 20;
    }
    ASSIGN_LOW(res,resdb_inf.d);
    if(supDone==0){
    /* Rest of argument reduction for accurate phase */
    Mul133(&msLog2Div2LMultKh_sup,&msLog2Div2LMultKm_sup,&msLog2Div2LMultKl_sup,kd_sup,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
    t1_sup = x_sup + msLog2Div2LMultKh_sup;
    Add12Cond(rh_sup,t2_sup,t1_sup,msLog2Div2LMultKm_sup);
    Add12Cond(rm_sup,rl_sup,t2_sup,msLog2Div2LMultKl_sup);
    /* Table reads for accurate phase */
    tbl1l_sup = twoPowerIndex1[index1_sup].lo;
    tbl2l_sup = twoPowerIndex2[index2_sup].lo;
    /* Call accurate phase */
    exp_td_accurate(&polyTblh_sup, &polyTblm_sup, &polyTbll_sup, rh_sup, rm_sup, rl_sup, tbl1h_sup, tbl1m_sup, tbl1l_sup, tbl2h_sup, tbl2m_sup, tbl2l_sup); 
    /* Since the final multiplication is exact, we can do the final rounding before multiplying
       We overcome this way also the cases where the final result is not underflowed whereas the
       lower parts of the intermediate final result are.
    */
    RoundUpwards3(&res_sup,polyTblh_sup,polyTblm_sup,polyTbll_sup);
    /* Final multiplication with 2^M 
       We implement the multiplication in integer computations to overcome
       the problem of the non-representability of 2^1024 if M = 1024
    */
    resdb_sup.d = res_sup;
    resdb_sup.i[HI] += M_sup << 20;
    }
    ASSIGN_UP(res,resdb_sup.d);
    return res;
  } /* Accurate phase launched after rounding test*/
    
  if (roundable==2) {
    if (infDone==0){
    /* Rest of argument reduction for accurate phase */
    Mul133(&msLog2Div2LMultKh_inf,&msLog2Div2LMultKm_inf,&msLog2Div2LMultKl_inf,kd_inf,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
    t1_inf = x_inf + msLog2Div2LMultKh_inf;
    Add12Cond(rh_inf,t2_inf,t1_inf,msLog2Div2LMultKm_inf);
    Add12Cond(rm_inf,rl_inf,t2_inf,msLog2Div2LMultKl_inf);
    /* Table reads for accurate phase */
    tbl1l_inf = twoPowerIndex1[index1_inf].lo;
    tbl2l_inf = twoPowerIndex2[index2_inf].lo;
    /* Call accurate phase */
    exp_td_accurate(&polyTblh_inf, &polyTblm_inf, &polyTbll_inf, rh_inf, rm_inf, rl_inf, tbl1h_inf, tbl1m_inf, tbl1l_inf, tbl2h_inf, tbl2m_inf, tbl2l_inf); 
    /* Since the final multiplication is exact, we can do the final rounding before multiplying
       We overcome this way also the cases where the final result is not underflowed whereas the
       lower parts of the intermediate final result are.
    */

    RoundDownwards3(&res_inf,polyTblh_inf,polyTblm_inf,polyTbll_inf);
    /* Final multiplication with 2^M 
       We implement the multiplication in integer computations to overcome
       the problem of the non-representability of 2^1024 if M = 1024
    */

    resdb_inf.d = res_inf;
    resdb_inf.i[HI] += M_inf << 20;
    }
    ASSIGN_LOW(res,resdb_inf.d);
    if(supDone==0){
      resdb_sup.i[HI] += M_sup << 20;
    }
    ASSIGN_UP(res,resdb_sup.d);    
    return res;
  } /* Accurate phase launched after rounding test*/
  if(roundable==0)
  {
    if(supDone==0){
    /* Rest of argument reduction for accurate phase */
    Mul133(&msLog2Div2LMultKh_sup,&msLog2Div2LMultKm_sup,&msLog2Div2LMultKl_sup,kd_sup,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
    t1_sup = x_sup + msLog2Div2LMultKh_sup;
    Add12Cond(rh_sup,t2_sup,t1_sup,msLog2Div2LMultKm_sup);
    Add12Cond(rm_sup,rl_sup,t2_sup,msLog2Div2LMultKl_sup);
    /* Table reads for accurate phase */
    tbl1l_sup = twoPowerIndex1[index1_sup].lo;
    tbl2l_sup = twoPowerIndex2[index2_sup].lo;
    /* Call accurate phase */
    exp_td_accurate(&polyTblh_sup, &polyTblm_sup, &polyTbll_sup, rh_sup, rm_sup, rl_sup, tbl1h_sup, tbl1m_sup, tbl1l_sup, tbl2h_sup, tbl2m_sup, tbl2l_sup); 
    /* Since the final multiplication is exact, we can do the final rounding before multiplying
       We overcome this way also the cases where the final result is not underflowed whereas the
       lower parts of the intermediate final result are.
    */
    RoundUpwards3(&res_sup,polyTblh_sup,polyTblm_sup,polyTbll_sup);
    /* Final multiplication with 2^M 
       We implement the multiplication in integer computations to overcome
       the problem of the non-representability of 2^1024 if M = 1024
    */
    resdb_sup.d = res_sup;
    resdb_sup.i[HI] += M_sup << 20;
    }
    ASSIGN_UP(res,resdb_sup.d);
    if (infDone==0){
    /* Rest of argument reduction for accurate phase */
    Mul133(&msLog2Div2LMultKh_inf,&msLog2Div2LMultKm_inf,&msLog2Div2LMultKl_inf,kd_inf,msLog2Div2Lh,msLog2Div2Lm,msLog2Div2Ll);
    t1_inf = x_inf + msLog2Div2LMultKh_inf;
    Add12Cond(rh_inf,t2_inf,t1_inf,msLog2Div2LMultKm_inf);
    Add12Cond(rm_inf,rl_inf,t2_inf,msLog2Div2LMultKl_inf);
    /* Table reads for accurate phase */
    tbl1l_inf = twoPowerIndex1[index1_inf].lo;
    tbl2l_inf = twoPowerIndex2[index2_inf].lo;
    /* Call accurate phase */
    exp_td_accurate(&polyTblh_inf, &polyTblm_inf, &polyTbll_inf, rh_inf, rm_inf, rl_inf, tbl1h_inf, tbl1m_inf, tbl1l_inf, tbl2h_inf, tbl2m_inf, tbl2l_inf); 
    /* Since the final multiplication is exact, we can do the final rounding before multiplying
       We overcome this way also the cases where the final result is not underflowed whereas the
       lower parts of the intermediate final result are.
    */

    RoundDownwards3(&res_inf,polyTblh_inf,polyTblm_inf,polyTbll_inf);
    /* Final multiplication with 2^M 
       We implement the multiplication in integer computations to overcome
       the problem of the non-representability of 2^1024 if M = 1024
    */

    resdb_inf.d = res_inf;
    resdb_inf.i[HI] += M_inf << 20;
    }
    ASSIGN_LOW(res,resdb_inf.d);
    return res;
  } /* Accurate phase launched after rounding test*/

  return res;
}