Example #1
0
double Tile_Engine::get_y_collision_move(double y1, double y2, double x1, double x_size, double y_size) {
	double pos_y = y1;
	if (y2 > y1 ) {
		int x_start = floor(x1/32.0);
		int x_end   = floor(nextafter(x_size+x1, x_size-1)/32.0);
		int y_start = floor(nextafter(y_size+y1, y_size-1)/32.0);
		int y_end   = floor(nextafter(y_size+y2, y_size-1)/32.0);
		for (int i = y_start; i <= y_end; i++) {
			for (int k = x_start; k <= x_end; k++) {
				if (getTile(k, i)->getType() == COLLIDES) {
					return pos_y;
				}
			}
			pos_y = (i==y_end)?y2:(double)(i+1)*32.0-y_size;//-nextafter(y_size, y_size-1);
		}
	} else {
		int x_start = floor(x1/32.0);
		int x_end   = floor(nextafter(x_size+x1,x_size-1)/32.0);
		int y_start = floor(y1/32.0);
		int y_end   = floor(y2/32.0);
		for (int i = y_start; i >= y_end; i--) {
			for (int k = x_start; k <= x_end; k++) {
				if (getTile(k, i)->getType() == COLLIDES) {
					return pos_y;
				}
			}
			pos_y = (i==y_end)?y2:(32*i);
		}
	}
	return pos_y;
}
Example #2
0
void test_fp_utilities( void )
{
#if __STDC_VERSION__ >= 199901L
    printf( "Testing C99 miscellaneous functions...\n" );

    VERIFY( CompDbl( copysign( -2.0, 1.0), 2.0 ) );
    VERIFY( CompDbl( copysign( -2.0, -1.0), -2.0 ) );
    VERIFY( CompDbl( copysign( 2.0, -1.0), -2.0 ) );
    VERIFY( CompDbl( copysign( 2.0, 1.0), 2.0 ) );
    
    VERIFY( CompDbl( fmax( 2.0, 1.0), 2.0 ) );
    VERIFY( CompDbl( fmax( -2.0, -1.0), -1.0 ) );
    VERIFY( CompDbl( fmin( 2.0, 1.0), 1.0 ) );
    VERIFY( CompDbl( fmin( -2.0, -1.0), -2.0 ) );
    
    VERIFY( CompDbl( fma( 2.0, 3.0, 4.0), 10.0 ) );
    VERIFY( CompDbl( fma( 2.0, 3.0, -4.0), 2.0 ) );
    VERIFY( CompDbl( fma( -2.0, 3.0, 4.0), -2.0 ) );
    VERIFY( CompDbl( fma( -2.0, -3.0, 4.0), 10.0 ) );
    
    VERIFY( CompDbl( fdim( 3.0, 2.0), 1.0 ) );
    VERIFY( CompDbl( fdim( 2.0, 3.0), 0.0 ) );
    
    VERIFY( CompDbl( nextafter( 1.0, 2.0), 1.0+1.0E-16 ) );
    VERIFY( CompDbl( nextafter( 1.0, 0.0), 1.0-1.0E-16 ) );
    
    VERIFY( CompDbl( scalbn( 1.0, 3.0), 8.0 ) );
    VERIFY( CompDbl( scalbn( 4.0, 3.0), 32.0 ) );
#endif
}
Example #3
0
void test_nextafter()
{
    static_assert((std::is_same<decltype(nextafter((double)0, (double)0)), double>::value), "");
    static_assert((std::is_same<decltype(nextafterf(0,0)), float>::value), "");
    static_assert((std::is_same<decltype(nextafterl(0,0)), long double>::value), "");
    assert(nextafter(0,1) == hexfloat<double>(0x1, 0, -1074));
}
Example #4
0
double Tile_Engine::get_x_collision_move(double x1, double x2, double y1, double x_size, double y_size) {
	double pos_x = x1;
	if (x2 > x1 ) { //Player bewegt sich rechts
		int y_start = floor(y1/32.0);
		int y_end   = floor(nextafter(y_size+y1, y_size-1)/32.0);
		int x_start = floor(nextafter(x_size+x1, x_size-1)/32.0);
		int x_end   = floor(nextafter(x_size+x2, x_size-1)/32.0);
		for (int i = x_start; i <= x_end; i++) {
			for (int k = y_start; k <= y_end; k++) {
				if (getTile(i, k)->getType() == COLLIDES) {
					return pos_x;
				}
			}
			pos_x = (i==x_end)?x2:(double)(i+1)*32.0-x_size;//-nextafter(x_size, x_size-1);
		}
	} else if (x2 < x1){ //Player bewegt sich links
		int y_start = floor(y1/32.0);
		int y_end   = floor(nextafter(y_size+y1, y_size-1)/32.0);
		int x_start = floor(x1/32.0);
		int x_end   = floor(x2/32.0);
		for (int i = x_start; i >= x_end; i--) {
			for (int k = y_start; k <= y_end; k++) {
				if (getTile(i, k)->getType() == COLLIDES) {
					return pos_x;
				}
			}
			pos_x = (i==x_end)?x2:(32.0*i);
		}
	}
	return pos_x;
}
Example #5
0
RGBA32 makeRGBAFromCMYKA(float c, float m, float y, float k, float a)
{
    double colors = 1 - k;
    int r = static_cast<int>(nextafter(256, 0) * (colors * (1 - c)));
    int g = static_cast<int>(nextafter(256, 0) * (colors * (1 - m)));
    int b = static_cast<int>(nextafter(256, 0) * (colors * (1 - y)));
    return makeRGBA(r, g, b, static_cast<float>(nextafter(256, 0) * a));
}
TEST_F(SerializationTest, FloatingTypesTest) {
  HasManyFloats hmf;
  hmf.a = nextafter(10000.0f, 10000.1f);
  hmf.b = nextafter(20000.0, 20000.1);
  hmf.c = nextafter(30000.0L, 30000.1L);

  std::stringstream ss;
  leap::Serialize(ss, hmf);
  auto deserialized = leap::Deserialize<HasManyFloats>(ss);
  ASSERT_EQ(hmf.a, deserialized->a) << "Float datatype not properly round-trip serialized";
  ASSERT_EQ(hmf.b, deserialized->b) << "Double datatype not properly round-trip serialized";
  ASSERT_EQ(hmf.c, deserialized->c) << "Long double datatype not properly round-trip serialized";
}
Example #7
0
ScmObj Scm_MakeBignumFromDouble(double val)
{
    if (LONG_MIN <= val
#if SIZEOF_LONG == 4
        && val <= LONG_MAX
#else
        && val <= nextafter((double)LONG_MAX, 0.0)
#endif
        )
        return Scm_MakeBignumFromSI((long)val);

    int exponent, sign;
    ScmObj mantissa = Scm_DecodeFlonum(val, &exponent, &sign);
    if (!SCM_NUMBERP(mantissa)) {
        Scm_Error("can't convert %lf to an integer", val);
    }
    ScmObj b = Scm_Ash(mantissa, exponent);
    if (sign < 0) b = Scm_Negate(b);
    /* always returns bignum */
    if (SCM_INTP(b)) {
        return Scm_MakeBignumFromSI(SCM_INT_VALUE(b));
    } else {
        return b;
    }
}
int main() {
    double x = 1.0;
    double y = 1.0;
    int i = 1;
    acosh(x);
    asinh(x);
    atanh(x);
    cbrt(x);
    expm1(x);
    erf(x);
    erfc(x);
    isnan(x);
    j0(x);
    j1(x);
    jn(i,x);
    ilogb(x);
    logb(x);
    log1p(x);
    rint(x);
    y0(x);
    y1(x);
    yn(i,x);
#   ifdef _THREAD_SAFE
    gamma_r(x,&i);
    lgamma_r(x,&i);
#   else
    gamma(x);
    lgamma(x);
#   endif
    hypot(x,y);
    nextafter(x,y);
    remainder(x,y);
    scalb(x,y);
    return 0;
}
Example #9
0
/**
 * Santiago Akle 
 * ICME Stanford University 2014
 *
 * Exemplifies the use of wrightOmega 
 *
 * */
int main(void)
{   
    pfloat r = 0.0;
    pfloat z = 1.0;
    pfloat w = 0.0;
    pfloat maxerr = 0.0;
    pfloat maxeval = 0.0;
    pfloat smallest = z;
    int i    = 0;
    
    //Caculate the factor that will skip 2^25 floating points
    pfloat scaling = nextafter(1.0,2.0); //1+eps
    for(;i<27;i++)
        scaling        = scaling*scaling;
 
    for(i=0;i<1E9;i++)
    {
        z *= scaling;
        w = wrightOmega(z);
        r = w+log(w)-z;
        r = fabs(r); //abs r
        r = r/fabs(z);
        if(r>maxerr)
        {
            maxerr = r;
            maxeval = w;
        }
    }
    pfloat largest = z;
    printf("Largerst relative error %e achieved at %e\n",maxerr,maxeval);
    printf("Smallest number evaluated %e largest %e range %e\n",smallest,largest,largest-smallest);
}
Example #10
0
static bool parseRGBParameters(CSSParserTokenRange& range, RGBA32& result, bool parseAlpha)
{
    ASSERT(range.peek().functionId() == CSSValueRgb || range.peek().functionId() == CSSValueRgba);
    CSSParserTokenRange args = consumeFunction(range);
    CSSPrimitiveValue* colorParameter = consumeInteger(args);
    if (!colorParameter)
        colorParameter = consumePercent(args, ValueRangeAll);
    if (!colorParameter)
        return false;
    const bool isPercent = colorParameter->isPercentage();
    int colorArray[3];
    colorArray[0] = clampRGBComponent(*colorParameter);
    for (int i = 1; i < 3; i++) {
        if (!consumeCommaIncludingWhitespace(args))
            return false;
        colorParameter = isPercent ? consumePercent(args, ValueRangeAll) : consumeInteger(args);
        if (!colorParameter)
            return false;
        colorArray[i] = clampRGBComponent(*colorParameter);
    }
    if (parseAlpha) {
        if (!consumeCommaIncludingWhitespace(args))
            return false;
        double alpha;
        if (!consumeNumberRaw(args, alpha))
            return false;
        // Convert the floating pointer number of alpha to an integer in the range [0, 256),
        // with an equal distribution across all 256 values.
        int alphaComponent = static_cast<int>(clampTo<double>(alpha, 0.0, 1.0) * nextafter(256.0, 0.0));
        result = makeRGBA(colorArray[0], colorArray[1], colorArray[2], alphaComponent);
    } else {
        result = makeRGB(colorArray[0], colorArray[1], colorArray[2]);
    }
    return args.atEnd();
}
template <int N, typename T> static double test_parse_fixed_r(skiatest::Reporter* reporter,
                                                              double low, double high, double inc)
{
    double SK_FixedMax_double = nextafter(1 << (sizeof(T) * CHAR_BIT - N - 1), 0.0);
    double SK_FixedEpsilon_double = (1.0 / (1 << N));
    double maxError = 0;
    char buffer[64];
    for (double f = low; f < high; f += inc) {
        SkString s;
        // 'sprintf' formatting as expected depends on the current locale being "C".
        // We currently expect tests and tools to run in the "C" locale.
        sprintf(buffer, "%.20f", f);
        T fix;
        bool b = parse_fixed<N>(buffer, &fix);
        if (b) {
            double f2 = fix * SK_FixedEpsilon_double;
            double error = fabs(f - f2);
            REPORTER_ASSERT(reporter,  error <= SK_FixedEpsilon_double);
            maxError = SkTMax(maxError, error);
        } else {
            REPORTER_ASSERT(reporter, f < -SK_FixedMax_double || SK_FixedMax_double < f);
        }
    }

    //SkDebugf("maxError: %.20f\n", maxError);
    return maxError;
}
Example #12
0
File: math.c Project: freeVM/freeVM
jdouble
internal_nextafter(jdouble arg1,jdouble arg2){
  jdouble result;

  result = nextafter (arg1,arg2);

  return result;
}
Example #13
0
extern "C" void *Texture2D_create(Vec2i &size, void *data,
    uint32_t type, uint32_t flags)
{
  Texture2D *self = (Texture2D*) alignedMalloc(sizeof(Texture2D));
  self->size      = size;

  // Due to float rounding frac(x) can be exactly 1.0f (e.g. for very small
  // negative x), although it should be strictly smaller than 1.0f. We handle
  // this case by having sizef slightly smaller than size, such that
  // frac(x)*sizef is always < size.
  self->sizef = Vec2f(nextafter((float)size.x, -1.0f), nextafter((float)size.y, -1.0f));
  self->halfTexel = Vec2f(0.5f/size.x, 0.5f/size.y);
  self->data = data;
  self->get = Texture2D_get_addr(type, flags & TEXTURE_FILTER_NEAREST);

  return self;
}
Example #14
0
void
Math_nextafter(void *fp)
{
	F_Math_nextafter *f;

	f = fp;

	*f->ret = nextafter(f->x, f->y);
}
Example #15
0
_f_real8
_NEAREST(_f_real8 x, _f_real8 s)
{
#ifdef KEY /* Bug 10771 */
   if (s == (_f_real8) 0.0) {
	   _lerror (_LELVL_ABORT, FENEARZS);
   }
  _f_int8 infinity =
    signbit(s) ? (0x8000000000000000ull | IEEE_64_INFINITY) : IEEE_64_INFINITY;
  _f_real8 result = nextafter(x, * (_f_real8 *) &infinity);
  return result;
#elif 0 /* KEY Bug 3399 */
	/* See comment in _NEAREST_4 */
	REGISTER_8 x_reg;
	int positive_s = (s > (_f_real8) 0.0);

	if (s == (_f_real8) 0.0) {
		_lerror (_LELVL_ABORT, FENEARZS);
	}

	x_reg.f = x;

	if (IEEE_64_EXPO_ALL_ONES(x_reg.ui)) {
		return x;
	}

	if (x == (_f_real8) 0.0) { /* either +0.0 or -0.0 */
		x_reg.ui = positive_s ? 1 : (IEEE_64_SIGN_BIT | 1);
	} else {
		int increment = (positive_s == (x > (_f_real8) 0.0)) ? 1 : -1;
		x_reg.ui += increment;
	}

	return x_reg.f;
#else
	REGISTER_8 s1, s2;
	s1.f = x;
	if (s == 0.0) {
		_lerror (_LELVL_ABORT, FENEARZS);
	}
	s2.ui = (s1.f > 0) ? LL_CONST(0x1) : -(LL_CONST(0x1));
	if (s1.f == 0.0) {
		s1.f = (s > 0.0) ? TINY_REAL8_F90 : -TINY_REAL8_F90;
	} else if (s > 0.0) {
		s1.ui += s2.ui;
	} else {
		s1.ui -= s2.ui;
	}
	if (isnormal64(s1.ui))
		return s1.f;
	if (x > 1.0 || x < -1.0)
		return s1.f;
	return (0.0);
#endif /* KEY */
}
Example #16
0
bool Tile_Engine::does_bottom_collide(position _pos, position _size) {
	int _y      = floor((_size.y+_pos.y)/32.0);
	int x_start = floor(_pos.x/32.0);
	int x_end   = floor(nextafter(_size.x+_pos.x, _size.x-1))/32;
	for (int i = x_start; i <= x_end; i++) {
		if (getTile(i, _y)->getType() == COLLIDES) {
			return COLLIDES;
		}
	}
	return N_COLLIDES;
}
Example #17
0
static inline bool parseAlphaValue(const CharacterType*& string,
                                   const CharacterType* end,
                                   const char terminator,
                                   int& value) {
  while (string != end && isHTMLSpace<CharacterType>(*string))
    string++;

  bool negative = false;

  if (string != end && *string == '-') {
    negative = true;
    string++;
  }

  value = 0;

  int length = end - string;
  if (length < 2)
    return false;

  if (string[length - 1] != terminator || !isASCIIDigit(string[length - 2]))
    return false;

  if (string[0] != '0' && string[0] != '1' && string[0] != '.') {
    if (checkForValidDouble(string, end, terminator)) {
      value = negative ? 0 : 255;
      string = end;
      return true;
    }
    return false;
  }

  if (length == 2 && string[0] != '.') {
    value = !negative && string[0] == '1' ? 255 : 0;
    string = end;
    return true;
  }

  if (isTenthAlpha(string, length - 1)) {
    static const int tenthAlphaValues[] = {0,   25,  51,  76,  102,
                                           127, 153, 179, 204, 230};
    value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
    string = end;
    return true;
  }

  double alpha = 0;
  if (!parseDouble(string, end, terminator, alpha))
    return false;
  value = negative ? 0 : static_cast<int>(alpha * nextafter(256.0, 0.0));
  string = end;
  return true;
}
Example #18
0
IGL_INLINE void igl::copyleft::cgal::assign_scalar(
  const typename CGAL::Epeck::FT & _cgal,
  float& d)
{
  // FORCE evaluation of the exact type otherwise interval might be huge.
  const typename CGAL::Epeck::FT cgal = _cgal.exact();
  const auto interval = CGAL::to_interval(cgal);
  d = interval.first;
  do {
      const float next = nextafter(d, interval.second);
      if (CGAL::abs(cgal-d) < CGAL::abs(cgal-next)) break;
      d = next;
  } while (d < interval.second);
}
Example #19
0
IntRect RenderSlider::thumbRect()
{
    if (!m_thumb)
        return IntRect();

    IntRect thumbRect;
    RenderBox* thumb = toRenderBox(m_thumb->renderer());

    thumbRect.setWidth(thumb->style()->width().calcMinValue(contentWidth()));
    thumbRect.setHeight(thumb->style()->height().calcMinValue(contentHeight()));

    double fraction = sliderPosition(static_cast<HTMLInputElement*>(node()));
    IntRect contentRect = contentBoxRect();
    if (style()->appearance() == SliderVerticalPart || style()->appearance() == MediaVolumeSliderPart) {
        thumbRect.setX(contentRect.x() + (contentRect.width() - thumbRect.width()) / 2);
        thumbRect.setY(contentRect.y() + static_cast<int>(nextafter((contentRect.height() - thumbRect.height()) + 1, 0) * (1 - fraction)));
    } else {
        thumbRect.setX(contentRect.x() + static_cast<int>(nextafter((contentRect.width() - thumbRect.width()) + 1, 0) * fraction));
        thumbRect.setY(contentRect.y() + (contentRect.height() - thumbRect.height()) / 2);
    }

    return thumbRect;
}
Example #20
0
File: main.cpp Project: CCJY/coliru
int main()
{
    float from1 = 0, to1 = nextafterf(0, 1);
    printf("The next representable float after %.2f (%a) is %.20g (%a)\n",
           from1, from1, to1, to1);
 
    float from2 = 1, to2 = nextafterf(1, 2);
    printf("The next representable float after %.2f (%a) is %.23f (%a)\n",
           from2, from2, to2, to2);
 
    double from3 = nextafter(0.1, 0), to3 = 0.1;
    printf("The number 0.1 lies between two valid doubles:\n    %.56f (%a)\nand %.55f  (%a)\n",
           from3, from3, to3, to3);
 
    {
        #pragma STDC FENV_ACCESS ON
        feclearexcept(FE_ALL_EXCEPT);
        double from4 = DBL_MAX, to4 = nextafter(DBL_MAX, INFINITY);
        printf("The next representable double after %.2g (%a) is %.23f (%a)\n",
               from4, from4, to4, to4);
        if(fetestexcept(FE_OVERFLOW)) puts("   raised FE_OVERFLOW");
        if(fetestexcept(FE_INEXACT)) puts("   raised FE_INEXACT");
    } // end FENV_ACCESS block
}
Example #21
0
// all values are in the range of 0 to 1.0
RGBA32 makeRGBAFromHSLA(double hue, double saturation, double lightness, double alpha)
{
    const double scaleFactor = nextafter(256.0, 0.0);

    if (!saturation) {
        int greyValue = static_cast<int>(lightness * scaleFactor);
        return makeRGBA(greyValue, greyValue, greyValue, static_cast<int>(alpha * scaleFactor));
    }

    double temp2 = lightness < 0.5 ? lightness * (1.0 + saturation) : lightness + saturation - lightness * saturation;
    double temp1 = 2.0 * lightness - temp2;

    return makeRGBA(static_cast<int>(calcHue(temp1, temp2, hue + 1.0 / 3.0) * scaleFactor),
                    static_cast<int>(calcHue(temp1, temp2, hue) * scaleFactor),
                    static_cast<int>(calcHue(temp1, temp2, hue - 1.0 / 3.0) * scaleFactor),
                    static_cast<int>(alpha * scaleFactor));
}
int
main(int argc, char *argv[])
{
    assert(test(nextafter(0.0, 0.0), 0.0));
    assert(test(nextafter(-0.0, 0.0), 0.0));
    assert(test(nextafter(0.0, -0.0), -0.0));
    assert(test(nextafter(-0.0, -0.0), -0.0));

    assert(test(nextafterf(0.0F, 0.0F), 0.0F));
    assert(test(nextafterf(-0.0F, 0.0F), 0.0F));
    assert(test(nextafterf(0.0F, -0.0F), -0.0F));
    assert(test(nextafterf(-0.0F, -0.0F), -0.0F));

    assert(test(nextafterl(0.0L, 0.0L), 0.0L));
    assert(test(nextafterl(-0.0L, 0.0L), 0.0L));
    assert(test(nextafterl(0.0L, -0.0L), -0.0L));
    assert(test(nextafterf(-0.0L, -0.0L), -0.0L));

    assert(test(nextafter(NAN, 1.0), NAN));
    assert(test(nextafter(1.0, NAN), NAN));
    assert(test(nextafter(NAN, NAN), NAN));

    assert(test(nextafterf(NAN, 1.0F), NAN));
    assert(test(nextafterf(1.0F, NAN), NAN));
    assert(test(nextafterf(NAN, NAN), NAN));

    assert(test(nextafterl(NAN, 1.0L), NAN));
    assert(test(nextafterl(1.0L, NAN), NAN));
    assert(test(nextafterl(NAN, NAN), NAN));

    assert(test(nextafter(0x1.fffffffffffffp+0, INFINITY), 0x1p1));
    assert(test(nextafter(0x1p1, -INFINITY), 0x1.fffffffffffffp+0));

    assert(test(nextafterf(0x1.fffffep+0f, INFINITY), 0x1p1f));
    assert(test(nextafterf(0x1p1f, -INFINITY), 0x1.fffffep+0f));

    return (0);
}
Example #23
0
int main(int argc, char *argv[])
{
	int i;
	float f;
	double d;
	long double ld;
	char *eptr;

	for (i = 1; i < argc; i++) {
		errno = 0;
		f = strtof(argv[i], &eptr);
		f = nextafterf(f, INFINITY);
		printf("%a  (*eptr:%d errno:%d)\n", f, *eptr, errno);
		errno = 0;
		d = strtod(argv[i], &eptr);
		d = nextafter(d, INFINITY);
		printf("%a  (*eptr:%d errno:%d)\n", d, *eptr, errno);
		errno = 0;
		ld = strtold(argv[i], &eptr);
		ld = nextafterl(ld, INFINITY);
		printf("%La  (*eptr:%d errno:%d)\n", ld, *eptr, errno);
	}
	return 0;
}
static inline GFC_REAL_8
almostone_r8 ()
{
#ifdef HAVE_NEXTAFTER
  return nextafter (1.0, 0.0);
#else
  static volatile GFC_REAL_8 val = 0.0;
  GFC_REAL_8 x;

  if (val != 0.0)
    return val;

  val = 0.9999;
  do
    {
      x = val;
      val = (val + 1.0) / 2.0;
    }
  while (val > x && val < 1.0);
  if (val == 1.0)
    val = x;
  return val;
#endif
}
Example #25
0
double epsD(double x) {
   x = copysign(x, 1.0);
   double y = nextafter(x, INFINITY);
   return y-x;
}
static char* toStringWithRadix(RadixBuffer& buffer, double number, unsigned radix)
{
    ASSERT(std::isfinite(number));
    ASSERT(radix >= 2 && radix <= 36);

    // Position the decimal point at the center of the string, set
    // the startOfResultString pointer to point at the decimal point.
    char* decimalPoint = buffer + sizeof(buffer) / 2;
    char* startOfResultString = decimalPoint;

    // Extract the sign.
    bool isNegative = number < 0;
    if (std::signbit(number))
        number = -number;
    double integerPart = floor(number);

    // We use this to test for odd values in odd radix bases.
    // Where the base is even, (e.g. 10), to determine whether a value is even we need only
    // consider the least significant digit. For example, 124 in base 10 is even, because '4'
    // is even. if the radix is odd, then the radix raised to an integer power is also odd.
    // E.g. in base 5, 124 represents (1 * 125 + 2 * 25 + 4 * 5). Since each digit in the value
    // is multiplied by an odd number, the result is even if the sum of all digits is even.
    //
    // For the integer portion of the result, we only need test whether the integer value is
    // even or odd. For each digit of the fraction added, we should invert our idea of whether
    // the number is odd if the new digit is odd.
    //
    // Also initialize digit to this value; for even radix values we only need track whether
    // the last individual digit was odd.
    bool integerPartIsOdd = integerPart <= static_cast<double>(0x1FFFFFFFFFFFFFull) && static_cast<int64_t>(integerPart) & 1;
    ASSERT(integerPartIsOdd == static_cast<bool>(fmod(integerPart, 2)));
    bool isOddInOddRadix = integerPartIsOdd;
    uint32_t digit = integerPartIsOdd;

    // Check if the value has a fractional part to convert.
    double fractionPart = number - integerPart;
    if (fractionPart) {
        // Write the decimal point now.
        *decimalPoint = '.';

        // Higher precision representation of the fractional part.
        Uint16WithFraction fraction(fractionPart);

        bool needsRoundingUp = false;
        char* endOfResultString = decimalPoint + 1;

        // Calculate the delta from the current number to the next & previous possible IEEE numbers.
        double nextNumber = nextafter(number, std::numeric_limits<double>::infinity());
        double lastNumber = nextafter(number, -std::numeric_limits<double>::infinity());
        ASSERT(std::isfinite(nextNumber) && !std::signbit(nextNumber));
        ASSERT(std::isfinite(lastNumber) && !std::signbit(lastNumber));
        double deltaNextDouble = nextNumber - number;
        double deltaLastDouble = number - lastNumber;
        ASSERT(std::isfinite(deltaNextDouble) && !std::signbit(deltaNextDouble));
        ASSERT(std::isfinite(deltaLastDouble) && !std::signbit(deltaLastDouble));

        // We track the delta from the current value to the next, to track how many digits of the
        // fraction we need to write. For example, if the value we are converting is precisely
        // 1.2345, so far we have written the digits "1.23" to a string leaving a remainder of
        // 0.45, and we want to determine whether we can round off, or whether we need to keep
        // appending digits ('4'). We can stop adding digits provided that then next possible
        // lower IEEE value is further from 1.23 than the remainder we'd be rounding off (0.45),
        // which is to say, less than 1.2255. Put another way, the delta between the prior
        // possible value and this number must be more than 2x the remainder we'd be rounding off
        // (or more simply half the delta between numbers must be greater than the remainder).
        //
        // Similarly we need track the delta to the next possible value, to dertermine whether
        // to round up. In almost all cases (other than at exponent boundaries) the deltas to
        // prior and subsequent values are identical, so we don't need track then separately.
        if (deltaNextDouble != deltaLastDouble) {
            // Since the deltas are different track them separately. Pre-multiply by 0.5.
            Uint16WithFraction halfDeltaNext(deltaNextDouble, 1);
            Uint16WithFraction halfDeltaLast(deltaLastDouble, 1);

            while (true) {
                // examine the remainder to determine whether we should be considering rounding
                // up or down. If remainder is precisely 0.5 rounding is to even.
                int dComparePoint5 = fraction.comparePoint5();
                if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) {
                    // Check for rounding up; are we closer to the value we'd round off to than
                    // the next IEEE value would be?
                    if (fraction.sumGreaterThanOne(halfDeltaNext)) {
                        needsRoundingUp = true;
                        break;
                    }
                } else {
                    // Check for rounding down; are we closer to the value we'd round off to than
                    // the prior IEEE value would be?
                    if (fraction < halfDeltaLast)
                        break;
                }

                ASSERT(endOfResultString < (buffer + sizeof(buffer) - 1));
                // Write a digit to the string.
                fraction *= radix;
                digit = fraction.floorAndSubtract();
                *endOfResultString++ = radixDigits[digit];
                // Keep track whether the portion written is currently even, if the radix is odd.
                if (digit & 1)
                    isOddInOddRadix = !isOddInOddRadix;

                // Shift the fractions by radix.
                halfDeltaNext *= radix;
                halfDeltaLast *= radix;
            }
        } else {
            // This code is identical to that above, except since deltaNextDouble != deltaLastDouble
            // we don't need to track these two values separately.
            Uint16WithFraction halfDelta(deltaNextDouble, 1);

            while (true) {
                int dComparePoint5 = fraction.comparePoint5();
                if (dComparePoint5 > 0 || (!dComparePoint5 && (radix & 1 ? isOddInOddRadix : digit & 1))) {
                    if (fraction.sumGreaterThanOne(halfDelta)) {
                        needsRoundingUp = true;
                        break;
                    }
                } else if (fraction < halfDelta)
                    break;

                ASSERT(endOfResultString < (buffer + sizeof(buffer) - 1));
                fraction *= radix;
                digit = fraction.floorAndSubtract();
                if (digit & 1)
                    isOddInOddRadix = !isOddInOddRadix;
                *endOfResultString++ = radixDigits[digit];

                halfDelta *= radix;
            }
        }

        // Check if the fraction needs rounding off (flag set in the loop writing digits, above).
        if (needsRoundingUp) {
            // Whilst the last digit is the maximum in the current radix, remove it.
            // e.g. rounding up the last digit in "12.3999" is the same as rounding up the
            // last digit in "12.3" - both round up to "12.4".
            while (endOfResultString[-1] == radixDigits[radix - 1])
                --endOfResultString;

            // Radix digits are sequential in ascii/unicode, except for '9' and 'a'.
            // E.g. the first 'if' case handles rounding 67.89 to 67.8a in base 16.
            // The 'else if' case handles rounding of all other digits.
            if (endOfResultString[-1] == '9')
                endOfResultString[-1] = 'a';
            else if (endOfResultString[-1] != '.')
                ++endOfResultString[-1];
            else {
                // One other possibility - there may be no digits to round up in the fraction
                // (or all may be been rounded off already), in which case we may need to
                // round into the integer portion of the number. Remove the decimal point.
                --endOfResultString;
                // In order to get here there must have been a non-zero fraction, in which case
                // there must be at least one bit of the value's mantissa not in use in the
                // integer part of the number. As such, adding to the integer part should not
                // be able to lose precision.
                ASSERT((integerPart + 1) - integerPart == 1);
                ++integerPart;
            }
        } else {
            // We only need to check for trailing zeros if the value does not get rounded up.
            while (endOfResultString[-1] == '0')
                --endOfResultString;
        }

        *endOfResultString = '\0';
        ASSERT(endOfResultString < buffer + sizeof(buffer));
    } else
        *decimalPoint = '\0';

    BigInteger units(integerPart);

    // Always loop at least once, to emit at least '0'.
    do {
        ASSERT(buffer < startOfResultString);

        // Read a single digit and write it to the front of the string.
        // Divide by radix to remove one digit from the value.
        digit = units.divide(radix);
        *--startOfResultString = radixDigits[digit];
    } while (!!units);

    // If the number is negative, prepend '-'.
    if (isNegative)
        *--startOfResultString = '-';
    ASSERT(buffer <= startOfResultString);

    return startOfResultString;
}
Example #27
0
EXPORT_C double
fma(double x, double y, double z)
{
	#ifndef __SYMBIAN32__
	static const double split = 0x1p27 + 1.0;
	#else
	static const double split = 134217729;
	#endif //__SYMBIAN32__
	double xs, ys, zs;
	double c, cc, hx, hy, p, q, tx, ty;
	double r, rr, s;
	int oround;
	int ex, ey, ez;
	int spread;

	if (z == 0.0)
		return (x * y);
	if (x == 0.0 || y == 0.0)
		return (x * y + z);

	/* Results of frexp() are undefined for these cases. */
	if (!isfinite(x) || !isfinite(y) || !isfinite(z))
		return (x * y + z);

	xs = frexp(x, &ex);
	ys = frexp(y, &ey);
	zs = frexp(z, &ez);
	oround = fegetround();
	spread = ex + ey - ez;

	/*
	 * If x * y and z are many orders of magnitude apart, the scaling
	 * will overflow, so we handle these cases specially.  Rounding
	 * modes other than FE_TONEAREST are painful.
	 */
	if (spread > DBL_MANT_DIG * 2) {
		fenv_t env;
		feraiseexcept(FE_INEXACT);
		switch(oround) {
		case FE_TONEAREST:
			return (x * y);
		case FE_TOWARDZERO:
			if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
				return (x * y);
			feholdexcept(&env);
			r = x * y;
			if (!fetestexcept(FE_INEXACT))
				r = nextafter(r, 0);
			feupdateenv(&env);
			return (r);
		case FE_DOWNWARD:
			if (z > 0.0)
				return (x * y);
			feholdexcept(&env);
			r = x * y;
			if (!fetestexcept(FE_INEXACT))
				r = nextafter(r, -INFINITY);
			feupdateenv(&env);
			return (r);
		default:	/* FE_UPWARD */
			if (z < 0.0)
				return (x * y);
			feholdexcept(&env);
			r = x * y;
			if (!fetestexcept(FE_INEXACT))
				r = nextafter(r, INFINITY);
			feupdateenv(&env);
			return (r);
		}
	}
	if (spread < -DBL_MANT_DIG) {
		feraiseexcept(FE_INEXACT);
		if (!isnormal(z))
			feraiseexcept(FE_UNDERFLOW);
		switch (oround) {
		case FE_TONEAREST:
			return (z);
		case FE_TOWARDZERO:
			if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
				return (z);
			else
				return (nextafter(z, 0));
		case FE_DOWNWARD:
			if (x > 0.0 ^ y < 0.0)
				return (z);
			else
				return (nextafter(z, -INFINITY));
		default:	/* FE_UPWARD */
			if (x > 0.0 ^ y < 0.0)
				return (nextafter(z, INFINITY));
			else
				return (z);
		}
	}

	/*
	 * Use Dekker's algorithm to perform the multiplication and
	 * subsequent addition in twice the machine precision.
	 * Arrange so that x * y = c + cc, and x * y + z = r + rr.
	 */
	fesetround(FE_TONEAREST);

	p = xs * split;
	hx = xs - p;
	hx += p;
	tx = xs - hx;

	p = ys * split;
	hy = ys - p;
	hy += p;
	ty = ys - hy;

	p = hx * hy;
	q = hx * ty + tx * hy;
	c = p + q;
	cc = p - c + q + tx * ty;

	zs = ldexp(zs, -spread);
	r = c + zs;
	s = r - c;
	rr = (c - (r - s)) + (zs - s) + cc;

	spread = ex + ey;
	if (spread + ilogb(r) > -1023) {
		fesetround(oround);
		r = r + rr;
	} else {
		/*
		 * The result is subnormal, so we round before scaling to
		 * avoid double rounding.
		 */
		#ifndef __SYMBIAN32__
		p = ldexp(copysign(0x1p-1022, r), -spread);
		#else

		p = ldexp(copysign(0, r), -spread);


		#endif //__SYMBIAN32__
		c = r + p;
		s = c - r;
		cc = (r - (c - s)) + (p - s) + rr;
		fesetround(oround);
		r = (c + cc) - p;
	}
	return (ldexp(r, spread));
}
Example #28
0
long double nexttowardl(long double ld, long double td) {
  return nextafter((double)ld, (double)td);
}
Example #29
0
double nexttoward(double d, long double td) {
  return nextafter(d, (double)td);
}
Example #30
0
float nextafterf (float x, float y)
{
	return (float) nextafter( (double)x, (double)y );
}