src/Generic/values/NumberConverter.cpp
/**
 * Once you've converted verbal parts to int you can calculate how much it is.
 * This only works with numbers from 0 to 999999999 (less than 1 billion).  It will
 * also fail with numbers too big for int. Not language specific.
 **/
Once you've converted verbal parts to int you can calculate how much it is.
This only works with numbers from 0 to 999999999 (less than 1 billion).  It will
also fail with numbers too big for int. Not language specific.
Once you ' ve converted verbal parts to int you can calculate how much it is . This only works with numbers from 0 to 999999999 ( less than 1 billion ) . It will also fail with numbers too big for int . Not language specific .
int NumberConverter::calculateValue(const std::vector<int>& values) {
	bool bad_num = true;
	for (size_t i = 0; i < values.size(); ++i) {
		if (values[i] != 0) {
			bad_num = false;
			break;
		}
	}
	if (bad_num)
		return 0;
	std::vector<int> digits;
	for (size_t i = 0; i < 12; i++)
		digits.push_back(0);
	std::list<int> fixed;
	for (size_t i = 0; i < values.size(); ++i) {
		int value = values[i];
		if (value < 10 ||
			(value >= 10 && value <= 100 && value %10 == 0) ||
			value == 100 ||
			value == 1000 ||
			value == 1000000 ||
			value == 1000000000) {
			fixed.push_back(value);
		} else if ((value > 10 && value % 10 != 0 ) || 
				   (value > 90 && value != 100)) {     
		    std::list<int> toAdd;
			if (value % 10 != 0) {
				toAdd.push_front(value % 10); 
				value -= value % 10;
			}
			if (value % 100 != 0) {
				toAdd.push_front(value % 100); 
				value -= value % 100;
			}
			if (value) {
				toAdd.push_front(100); 
				if (value != 100)
					toAdd.push_front(value/100); 
			}
			while (toAdd.size() != 0) {
				fixed.push_back(toAdd.front());
				toAdd.pop_front();
			}
		} else {
			SessionLogger::info("NumberConverter") << "WARNING: Number conversion failed. " << value << " found mixed with textual numbers." << std::endl;
		}
	}
	fixed = normalizeHundreds(fixed);
	std::list< int > last_list;
	while (fixed.size() != 0 && 
		   (last_list.empty() || last_list.size() != fixed.size() ||
		   !std::equal(fixed.begin(), fixed.end(), last_list.begin()))) {
		last_list.clear();
		last_list.resize(fixed.size());
		std::copy(fixed.begin(), fixed.end(), last_list.begin());
		int ones = 0;
		int tens = 0;
		int hundreds = 0;
		int power_of_thousand = 1;
		for (int i = 0; i < 4; ++i) {
			if (i == 0) { 
				if (fixed.front() >= 100 && fixed.front() <= 900) {
					hundreds = fixed.front()/100;
					fixed.pop_front();
					if (fixed.size() == 0)
						break;
				}
			} else if (i == 1) { 
				if (fixed.front() >= 10 && fixed.front() <= 90) {
					tens = fixed.front()/10;
					fixed.pop_front();
					if (fixed.size() == 0)
						break;
				}
			} else if (i == 2) { 
				if (fixed.front() >= 1 && fixed.front() <= 9) {
					ones = fixed.front();
					fixed.pop_front();
					if (fixed.size() == 0)
						break;
				}
			} else { 
				if (fixed.front() >= 100) {
					power_of_thousand = fixed.front();
					fixed.pop_front();
				}
			}
		}
		switch (power_of_thousand) {
			case 1000000000: 
				digits[0] = hundreds;
				digits[1] = tens;
				digits[2] = ones;
				break;
			case 1000000: 
				digits[3] = hundreds;
				digits[4] = tens;
				digits[5] = ones;
				break;
			case 1000: 
				digits[6] = hundreds;
				digits[7] = tens;
				digits[8] = ones;
				break;
			case 1: 
				digits[9] = hundreds;
				digits[10] = tens;
				digits[11] = ones;
				break;
		}
	}
	int returnVal = 0;
	int power = 1;
	for (std::vector<int>::reverse_iterator it = digits.rbegin(); it != digits.rend(); it++) {
		returnVal += (power*(*it));
		power *= 10;
	}
	return returnVal;
}
int NumberConverter :: calculateValue ( const std :: vector < int > & values ) { bool bad_num = true ; for ( size_t i = 0 ; i < values . size ( ) ; ++ i ) { if ( values [ i ] != 0 ) { bad_num = false ; break ; } } if ( bad_num ) return 0 ; std :: vector < int > digits ; for ( size_t i = 0 ; i < 12 ; i ++ ) digits . push_back ( 0 ) ; std :: list < int > fixed ; for ( size_t i = 0 ; i < values . size ( ) ; ++ i ) { int value = values [ i ] ; if ( value < 10 || ( value >= 10 && value <= 100 && value % 10 == 0 ) || value == 100 || value == 1000 || value == 1000000 || value == 1000000000 ) { fixed . push_back ( value ) ; } else if ( ( value > 10 && value % 10 != 0 ) || ( value > 90 && value != 100 ) ) { std :: list < int > toAdd ; if ( value % 10 != 0 ) { toAdd . push_front ( value % 10 ) ; value -= value % 10 ; } if ( value % 100 != 0 ) { toAdd . push_front ( value % 100 ) ; value -= value % 100 ; } if ( value ) { toAdd . push_front ( 100 ) ; if ( value != 100 ) toAdd . push_front ( value / 100 ) ; } while ( toAdd . size ( ) != 0 ) { fixed . push_back ( toAdd . front ( ) ) ; toAdd . pop_front ( ) ; } } else { SessionLogger :: info ( " " ) << " " << value << " " << std :: endl ; } } fixed = normalizeHundreds ( fixed ) ; std :: list < int > last_list ; while ( fixed . size ( ) != 0 && ( last_list . empty ( ) || last_list . size ( ) != fixed . size ( ) || ! std :: equal ( fixed . begin ( ) , fixed . end ( ) , last_list . begin ( ) ) ) ) { last_list . clear ( ) ; last_list . resize ( fixed . size ( ) ) ; std :: copy ( fixed . begin ( ) , fixed . end ( ) , last_list . begin ( ) ) ; int ones = 0 ; int tens = 0 ; int hundreds = 0 ; int power_of_thousand = 1 ; for ( int i = 0 ; i < 4 ; ++ i ) { if ( i == 0 ) { if ( fixed . front ( ) >= 100 && fixed . front ( ) <= 900 ) { hundreds = fixed . front ( ) / 100 ; fixed . pop_front ( ) ; if ( fixed . size ( ) == 0 ) break ; } } else if ( i == 1 ) { if ( fixed . front ( ) >= 10 && fixed . front ( ) <= 90 ) { tens = fixed . front ( ) / 10 ; fixed . pop_front ( ) ; if ( fixed . size ( ) == 0 ) break ; } } else if ( i == 2 ) { if ( fixed . front ( ) >= 1 && fixed . front ( ) <= 9 ) { ones = fixed . front ( ) ; fixed . pop_front ( ) ; if ( fixed . size ( ) == 0 ) break ; } } else { if ( fixed . front ( ) >= 100 ) { power_of_thousand = fixed . front ( ) ; fixed . pop_front ( ) ; } } } switch ( power_of_thousand ) { case 1000000000 : digits [ 0 ] = hundreds ; digits [ 1 ] = tens ; digits [ 2 ] = ones ; break ; case 1000000 : digits [ 3 ] = hundreds ; digits [ 4 ] = tens ; digits [ 5 ] = ones ; break ; case 1000 : digits [ 6 ] = hundreds ; digits [ 7 ] = tens ; digits [ 8 ] = ones ; break ; case 1 : digits [ 9 ] = hundreds ; digits [ 10 ] = tens ; digits [ 11 ] = ones ; break ; } } int returnVal = 0 ; int power = 1 ; for ( std :: vector < int > :: reverse_iterator it = digits . rbegin ( ) ; it != digits . rend ( ) ; it ++ ) { returnVal += ( power * ( * it ) ) ; power *= 10 ; } return returnVal ; }
Once you've converted verbal parts to int you can calculate how much it is.
Once you ' ve converted verbal parts to int you can calculate how much it is .
// Fix fully fleshed out values: "270 million" should be [2, 100, 70, 1000000]
 // for the algorithm to work.
 // Handle complex values (i.e.: 237, this splits up the 237 to [2, 100, 30, 7])
 // Because of where this is placed it will never have to deal with
 // Values greater than 999 or less than 11:
 // Any value greater than 10, not divisible by 10
 // Or any value greater than 90 not equal to 100
 // 1s place
 // 10s place
 // 100s place
 // how many 100s
 // Store the last state of the list so that we make sure it changes between iterations.
 // The check is inefficient, but at least it prevents the code from getting stuck in an
 // infinite loop. A more thorough fix should be checked in soon.
 //Expecting hundreds
 // Expecting tens
 // Expecting ones
 // Expecting power-of-1000
 // Billion
 // Million
 // Thousand
 // One
 // This is dangerous because "power" overflows before the end of the sequence of digits
 // is reached. However, the bad effects are seen only if there is a nonzero
 // digit in the first three or so positions, which will be rare.
 // Note that in a 32-bit implementation, INT_MAX == 2,147,483,647.
