Esempio n. 1
0
pgsRealGen::pgsRealGen(const MAPM & min, const MAPM & max,
		const UCHAR & precision, const bool & sequence, const long & seed) :
	pgsObjectGen(seed), m_min(wxMin(min, max)), m_max(wxMax(min, max)),
			m_range(m_max - m_min), m_sequence(sequence)
{
	m_pow = MAPM(10).pow(MAPM(precision));
	m_int_max = pgsMapm::pgs_mapm_round(m_range * m_pow) + 1;

	m_randomizer = is_sequence()
			? pgsRandomizer(pnew pgsIntegerGen::pgsSequentialIntGen(m_int_max, m_seed))
			: pgsRandomizer(pnew pgsIntegerGen::pgsNormalIntGen(m_int_max, m_seed));
}
Esempio n. 2
0
/** Rounds this Numeric to the given precision, and rounds a half to even */
Numeric::Ptr ATDecimalOrDerivedImpl::roundHalfToEven(const Numeric::Ptr &precision, const DynamicContext* context) const {
  ATDecimalOrDerived::Ptr decimal_precision = (const Numeric::Ptr)precision->castAs(this->getPrimitiveTypeIndex(), context);
  MAPM exp = MAPM(10).pow(((ATDecimalOrDerivedImpl*)(const ATDecimalOrDerived*)decimal_precision)->_decimal);
  MAPM value = _decimal * exp;
  bool halfVal = false;

  // check if we're rounding on a half value 
  if((value-0.5) == (value.floor())) {
    halfVal = true;
  }
  value = _decimal * exp + 0.5;
  value = value.floor();

  // if halfVal make sure what we return has the least significant digit even
  if (halfVal) {
    if(value.is_odd()) {
      value = value - 1;
    }
  }
  value = value / exp;  
  // if integer, return xs:integer, otherwise xs:decimal    
  if(_isInteger) {
    return context->getItemFactory()->createInteger(value, context);
  }
  return context->getItemFactory()->createDecimal(value, context);
}
Esempio n. 3
0
Numeric::Ptr ATFloatOrDerivedImpl::atan(const DynamicContext* context) const {
    switch (_state) {
    case NaN:
        return this;
    case INF:
        return newFloat((MM_HALF_PI), context);
    case NEG_INF:
        return newFloat(MAPM(MM_HALF_PI).neg(), context);
    case NEG_NUM:
    case NUM:
        return newFloat(_float.atan(), context);
    default:
        assert(false);
        return 0;  // should never get here
    }
}
Esempio n. 4
0
/** Rounds this Numeric to the given precision, and rounds a half to even */
Numeric::Ptr ATFloatOrDerivedImpl::roundHalfToEven(const Numeric::Ptr &precision, const DynamicContext* context) const {
    switch (_state) {
    case NaN:
        return notANumber(context);
    case INF:
        return infinity(context);
    case NEG_INF:
        return negInfinity(context);
    case NEG_NUM:
    case NUM:
        break;
    default: {
        assert(false);
        return 0; // should never get here
    }
    }

    if (isZero() && isNegative())
        return this;

    ATFloatOrDerived::Ptr float_precision = (const Numeric::Ptr)precision->castAs(this->getPrimitiveTypeIndex(), context);
    MAPM exp = MAPM(10).pow(((ATFloatOrDerivedImpl*)(const ATFloatOrDerived*)float_precision)->_float);
    MAPM value = _float * exp;
    bool halfVal = false;

    // check if we're rounding on a half value
    if((value-0.5) == (value.floor())) {
        halfVal = true;
    }
    value = _float * exp + 0.5;
    value = value.floor();

    // if halfVal make sure what we return has the least significant digit even
    if (halfVal) {
        if(value.is_odd()) {
            value = value - 1;
        }
    }
    value = value / exp;

    // the spec doesn't actually say to do this, but djf believes this is the correct way to handle rounding of -ve values which will result in 0.0E0
    // if (value == 0 && isNegative())
    // return negZero(context);
    return newFloat(value, context);
}
Esempio n. 5
0
void pgsTestSuite::test_generator_real(void)
{
	const int nb_iterations = 500;

	// Generate *unique* numbers between 1 and 2 with 3 digits
	// Test the expected average: 1.5
	{
		pgsRealGen gen(1, 2, 3, true);
		TS_ASSERT(gen.is_sequence());
		MAPM sum = 0, avg, result;
		pgsVectorMapm sav;
		for (int i = 0; i < 1001; i++)
		{
			result = MAPM(gen.random().mb_str());
			TS_ASSERT(result >= 1 && result <= 2);
			TS_ASSERT(sav.Index(result) == wxNOT_FOUND);
			sum += result;
			sav.push_back(result);
		}
		avg = sum / (1001);
		TS_ASSERT(avg == MAPM("1500e-3"));
	}

	// Generate negative and positive *unique* integer numbers (precision == 0)
	// Expected average is of course 0
	{
		pgsRealGen gen("-50", "50", 0, true);
		TS_ASSERT(gen.is_sequence());
		MAPM sum = 0, result;
		pgsVectorMapm sav;
		for (int i = 0; i < 101; i++)
		{
			result = MAPM(gen.random().mb_str());
			TS_ASSERT(result >= -50 && result <= 50);
			sum += result;
			TS_ASSERT(sav.Index(result) == wxNOT_FOUND);
			sav.push_back(result);
		}
		TS_ASSERT(sav.size() == 101 && sum == 0);
	}

	// Test that two generators with same seed generate same values
	{
		pgsRealGen gen(0, 10000.567890, 6, false, 123456789L);
		pgsRealGen comparator(0, 10000.567890, 6, false, 123456789L);
		TS_ASSERT(!gen.is_sequence() && !comparator.is_sequence());
		wxString res_cmp;
		MAPM sum = 0, avg, result;
		for (int i = 0; i < nb_iterations; i++)
		{
			res_cmp = comparator.random();
			result = MAPM(gen.random().mb_str());
			TS_ASSERT(result >= 0 && result <= "1.0000567890e4");
			TS_ASSERT(result == MAPM(res_cmp.mb_str()));
			sum += result;
		}
		avg = sum / nb_iterations;
		TS_ASSERT(avg > 4500 && avg < 5500);
	}

	// Same thing as previous with min > max and seed == 0
	// min and max must be swapped
	// seed must be set to one otherwise we would have zeros only
	{
		pgsRealGen gen(10000.567890, 0, 6, true, 0);
		pgsRealGen comparator(10000.567890, 0, 6, true, 0);
		TS_ASSERT(gen.is_sequence() && comparator.is_sequence());
		wxString res_cmp;
		MAPM sum = 0, avg, result;
		for (int i = 0; i < nb_iterations; i++)
		{
			res_cmp = comparator.random();
			result = MAPM(gen.random().mb_str());
			TS_ASSERT(result >= 0 && result <= "1.0000567890e4");
			TS_ASSERT(result == MAPM(res_cmp.mb_str()));
			sum += result;
		}
		avg = sum / nb_iterations;
		TS_ASSERT(avg > 4500 && avg < 5500);
	}

	// Generate big numbers with a too low precision and test the string output
	// Last decimals should not be taken into account
	{
		pgsRealGen gen("123456789876.54321", "123456789876.5432134", 5, false);
		TS_ASSERT(!gen.is_sequence());
		MAPM result;
		for (int i = 0; i < nb_iterations; i++)
		{
			result = MAPM(gen.random().mb_str());
			TS_ASSERT(result == "123456789876.54321");
		}
	}

	// Generate numbers with exponents
	// Test the expected average: 1.5
	{
		pgsRealGen gen("0", "1e100", 0, false);
		TS_ASSERT(!gen.is_sequence());
		MAPM sum = 0, avg, result;
		for (int i = 0; i < nb_iterations; i++)
		{
			result = MAPM(gen.random().mb_str());
			TS_ASSERT(result >= "0" && result <= "1e100");
			sum += result;
		}
		avg = sum / nb_iterations;
		TS_ASSERT(avg >= "4.5e99" && avg <= "5.5e99");
	}

	// Test copy constructor
	{
		// Create a generator and generate values
		pgsRealGen gen(0, 10000.567890, 6, false);
		wxString result, res_cmp;
		for (int i = 0; i < nb_iterations / 2; i++)
		{
			result = gen.random();
		}
		
		// Copy this generator to a new one
		// Both generators must generate the same values
		pgsRealGen comparator(gen);
		TS_ASSERT(!gen.is_sequence() && !comparator.is_sequence());
		for (int i = nb_iterations / 2; i < nb_iterations; i++)
		{
			result = gen.random();
			res_cmp = comparator.random();
			TS_ASSERT(result == res_cmp);
		}
	}

	// Test assignment operator
	{
		// Create two different generators and generate values
		pgsRealGen gen(0, 10000.567890, 6, false);
		pgsRealGen comparator(1, 2, 3, true);
		wxString result, res_cmp;
		for (int i = 0; i < nb_iterations / 2; i++)
		{
			result = gen.random();
			res_cmp = comparator.random();
		}
		
		// Copy one of the generators to the other one
		// Both generators must generate the same values
		comparator = gen;
		TS_ASSERT(!gen.is_sequence() && !comparator.is_sequence());
		for (int i = nb_iterations / 2; i < nb_iterations; i++)
		{
			result = gen.random();
			res_cmp = comparator.random();
			TS_ASSERT(result == res_cmp);
		}
	}
}
void pgsTestSuite::test_generator_string(void)
{
	const int nb_iterations = 100;

	// Generate empty strings because of inconsistent arguments
	{
		pgsStringGen gen1(0, 0, 10);
		pgsStringGen gen2(10, 20, 0);
		// pgsStringGen gen3(-10, -20, 10);
		// pgsStringGen gen4(10, 20, -10);
		TS_ASSERT(gen1.random() == wxT(""));
		TS_ASSERT(gen2.random() == wxT(""));
		// TS_ASSERT(gen3.random() == wxT(""));
		// TS_ASSERT(gen4.random() == wxT(""));
	}

	// Generate strings with 'a' only
	{
		pgsVectorChar chars;
		chars.Add(wxT('a'));
		chars.Add(wxT('a'));
		pgsStringGen gen(2, 2, 3, wxDateTime::GetTimeNow(), chars);
		for (int i = 0; i < nb_iterations; i++)
		{
			TS_ASSERT(gen.random() == wxT("aa aa aa"));
		}
	}

	// Test strings that are in fact numbers
	// Test the size of generated strings
	{
		pgsVectorChar chars;
		chars.Add(wxT('1'));
		chars.Add(wxT('2'));
		chars.Add(wxT('3'));
		chars.Add(wxT('4'));
		pgsStringGen gen(5, 5, 1, wxDateTime::GetTimeNow(), chars);
		wxString result;
		for (int i = 0; i < nb_iterations; i++)
		{
			result = gen.random();
			long aux_res;
			result.ToLong(&aux_res);
			TS_ASSERT(MAPM(result.mb_str()) == aux_res && result.Length() == 5);
		}
	}

	// Test the size of generated strings
	{
		pgsStringGen gen(10, 11, 3, 123);
		pgsStringGen comparator(10, 11, 3, 123);
		wxString result;
		for (int i = 0; i < nb_iterations; i++)
		{
			result = gen.random();
			TS_ASSERT(result == comparator.random());
			TS_ASSERT(result.Length() >= 32 && result.Length() <= 35);
		}
	}

	// Test copy constructor
	{
		// Create a generator and generate values
		pgsStringGen gen(10, 11, 3, 123456789L);
		wxString result, res_cmp;
		for (int i = 0; i < nb_iterations / 2; i++)
		{
			result = gen.random();
		}
		
		// Copy this generator to a new one
		// Both generators must generate the same values
		pgsStringGen comparator(gen);
		for (int i = nb_iterations / 2; i < nb_iterations; i++)
		{
			result = gen.random();
			res_cmp = comparator.random();
			TS_ASSERT(result == res_cmp);
		}
	}

	// Test assignment operator
	{
		// Create two different generators and generate values
		pgsStringGen gen(20, 30, 20);
		pgsStringGen comparator(0, 0, 10);
		wxString result, res_cmp;
		for (int i = 0; i < nb_iterations / 2; i++)
		{
			result = gen.random();
			res_cmp = comparator.random();
		}
		
		// Copy one of the generators to the other one
		// Both generators must generate the same values
		comparator = gen;
		for (int i = nb_iterations / 2; i < nb_iterations; i++)
		{
			result = gen.random();
			res_cmp = comparator.random();
			TS_ASSERT(result == res_cmp);
		}
	}
}