예제 #1
0
파일: LIS.cpp 프로젝트: iduru/Library
// Longest Increasing Subsequence
int LIS(vector<int>& xs) {
    vector<int> L(xs.size(), INT_MAX);
    for (int i = 0; i < xs.size(); i++) {
        (*lower_bound(whole(L), xs[i])) = xs[i];
    }
    return lower_bound(whole(L), INT_MAX) - L.begin();
}
예제 #2
0
bool CSeqDBAtlas::GetFileSizeL(const string & fname,
                               TIndx        & length)
{
    Verify(true);
    // Fields: file-exists, file-length
    pair<bool, TIndx> data;

    map< string, pair<bool, TIndx> >::iterator i =
        m_FileSize.find(fname);

    if (i == m_FileSize.end()) {
        CFile whole(fname);
        Int8 file_length = whole.GetLength();

        if (file_length >= 0) {
            data.first  = true;
            data.second = SeqDB_CheckLength<Int8,TIndx>(file_length);
            if ((Uint8)file_length > m_MaxFileSize) m_MaxFileSize = file_length;
        } else {
            data.first  = false;
            data.second = 0;
        }

        m_FileSize[fname] = data;
    } else {
        data = (*i).second;
    }
    Verify(true);

    length = data.second;
    return data.first;
}
예제 #3
0
파일: NValue.cpp 프로젝트: DarkDare/voltdb
/**
 * Serialize sign and value using radix point (no exponent).
 */
std::string NValue::createStringFromDecimal() const {
    assert(!isNull());
    std::ostringstream buffer;
    TTInt scaledValue = getDecimal();
    if (scaledValue.IsSign()) {
        buffer << '-';
    }
    TTInt whole(scaledValue);
    TTInt fractional(scaledValue);
    whole /= NValue::kMaxScaleFactor;
    fractional %= NValue::kMaxScaleFactor;
    if (whole.IsSign()) {
        whole.ChangeSign();
    }
    buffer << whole.ToString(10);
    buffer << '.';
    if (fractional.IsSign()) {
        fractional.ChangeSign();
    }
    std::string fractionalString = fractional.ToString(10);
    for (int ii = static_cast<int>(fractionalString.size()); ii < NValue::kMaxDecScale; ii++) {
        buffer << '0';
    }
    buffer << fractionalString;
    return buffer.str();
}
예제 #4
0
void FileNameHandler::onReadFinished(std::tr1::shared_ptr<DenseData> fileContents,
        std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {

    mStats.resolved++;

    std::tr1::shared_ptr<RemoteFileMetadata> bad;
    if (!fileContents) {
        SILOG(transfer, error, "FileNameHandler couldn't find file '" << request->getURI() << "'");
        callback(bad);
        return;
    }

    FileHeaders emptyHeaders;
    Fingerprint fp = SparseData(fileContents).computeFingerprint();

    //Just treat everything as a single chunk for now
    Range::length_type file_size = fileContents->length();
    Range whole(0, file_size, LENGTH, true);
    Chunk chunk(fp, whole);
    ChunkList chunkList;
    chunkList.push_back(chunk);

    SharedChunkCache::getSingleton().getCache()->addToCache(fp, fileContents);
    std::tr1::shared_ptr<RemoteFileMetadata> met(new RemoteFileMetadata(fp, request->getURI(),
                file_size, chunkList, emptyHeaders));
    callback(met);
}
예제 #5
0
int main()
{
	//function prototypes
	int whole(float );

	int i;

	//convert and print values
	printf(" NUMBER  WHOLE NUM\n");
	printf("-------- ---------\n");

	printf("%8.3f %8d\n", 20.345, whole(20.345));
	printf("%8.3f %8d\n", 10.678, whole(10.678));
	printf("%8.3f %8d\n", 7.953, whole(7.953));
	printf("%8.3f %8d\n", 99.874, whole(99.874));
	

	return 0;
}
예제 #6
0
void	VerifyRequest::verify(const std::string &request) const
{
  std::bitset<8> first8(request.at(5));
  std::bitset<8> second8(request.at(6));
  std::bitset<16> whole(first8.to_string() + second8.to_string());

  if ((request.length() - HEADER_SIZE) == whole.to_ulong())
    {
      DataFromClient *manag = new DataFromClient(request);
      (void)manag;
    }
  else
    {

    }
}
/**
 * @note g must be connected
 * @return is the size of a part
 */
int check_bipartite_graph(vector<vector<int> > const & g) {
    int n = g.size();
    vector<char> used(n, -1);
    function<bool (int, int)> dfs = [&](int i, int parent) {
        for (int j : g[i]) {
            if (used[j] != -1) {
                if (used[j] == used[i]) {
                    return false;
                }
            } else {
                used[j] = used[i] ^ 1;
                if (not dfs(j, i)) return false;
            }
        }
        return true;
    };
    used[0] = 0;
    if (not dfs(0, -1)) return -1;
    return count(whole(used), 0);
}
예제 #8
0
/*
    Cracks the Vigenere cipher by looking at every keyLength-th letter,
    and then cracking that shift cipher. Since the key repeats, there is
    statistical information that is repeated in the ciphertext. This method
    cracks each character of the key in turn, and then returns the most
    statistically-likely plaintext. Note that this doesn't always lead to the
    best plaintext, but by printing off the intermediate better guesses,
    the actual plaintext can be revealed.
*/
std::string crackVigenereCipher(const std::string& ciphertext)
{
    float bestDeviation = 4096;
    std::string currentGuess;

    for (std::size_t keyLength = 1; keyLength <= 20; keyLength++)
    {
        std::string whole(ciphertext); //will be overridden

        for (std::size_t offset = 0; offset < keyLength; offset++)
        {
            std::string subStr;
            for (std::size_t j = offset; j < ciphertext.size(); j += keyLength)
                subStr += ciphertext[j];

            auto cracked = crackShiftCipher(subStr);
            for (std::size_t j = 0; j < subStr.size(); j++)
                whole[j * keyLength + offset] = cracked[j];
        }

        float dev = getDeviationFromEnglish(whole);

        if (dev < bestDeviation)
        {
            bestDeviation = dev;
            currentGuess = whole;

            std::cout << std::endl;
            std::cout << "Better guess! Keylength of " << keyLength << std::endl;
            std::cout << "Deviation from English: " << dev << std::endl;
            std::cout << currentGuess << std::endl;
        }
    }

    return currentGuess;
}
예제 #9
0
int compute_fine_weight(smap sm, kanji larger, kanji smaller, bool is_small) {
    
    int weight = 0;
    int i=0;
    while(i<larger.c_strokes) {
        int larger_idx_start = i;
        int smaller_idx = sm.m[i];
        while(i < larger.c_strokes && sm.m[i] == smaller_idx   ) {
            i++;
        }
        i--;
        int larger_idx_stop = i;
        int gamma = 10;
        if(larger_idx_stop > larger_idx_start) { // larger is a combined stroke
            // length of combined stroke
            int m=0;
            for(int j=larger_idx_start;j<=larger_idx_stop;j++) {
                m += larger.c_points[j];
            }
            int n=smaller.c_points[smaller_idx];
            gamma = (max(m,n)*10)/min(m,n);
        }
        int wi = 0;
        if(is_small) {
            wi = (gamma * whole_delta(smaller, smaller_idx, 
                larger, larger_idx_start, larger_idx_stop))/smaller.c_strokes;
        } else {
            wi = (gamma * whole(smaller, smaller_idx, 
                larger, larger_idx_start, larger_idx_stop))/smaller.c_strokes;
        }    
        weight += wi;
        // printf("(%i-%i,%i): %i\n",larger_idx_start,larger_idx_stop,smaller_idx,wi);
        i++;
    }
    return weight;
}
예제 #10
0
파일: board.cpp 프로젝트: jbytheway/nibbles
void Board::init(const LevelDefinition& definition)
{
  const uint32_t w = definition.get<fields::w>();
  const uint32_t h = definition.get<fields::h>();
  assert(w > 0);
  assert(h > 0);
  boost::multi_array<BoardState, 2>& array = get<states>();
  array.resize(boost::extents[w][h]);

  Block whole(0, 0, w, h);
  assign(whole, BoardState::empty);
  Block top(0, 0, w, 1);
  Block bottom(0, h-1, w, 1);
  Block left(0, 0, 1, h);
  Block right(w-1, 0, 1, h);
  assign(top, BoardState::wall);
  assign(bottom, BoardState::wall);
  assign(left, BoardState::wall);
  assign(right, BoardState::wall);
  BOOST_FOREACH(const Block& wall, definition.get<blocks>()) {
    assign(wall, BoardState::wall);
  }
  assert(definition.get<randomBlocks>().empty());
}
예제 #11
0
int
main P2C(int, argc,  string *, argv)
{
  register char *cp;
  int blanks_done, indent, i;
  char *program_name = "";

  kpse_set_program_name (argv[0], NULL); /* In case we use FATAL.  */

  for (i = 1; i < argc; i++)
    {
      if (STREQ(argv[i],"-t"))
	tex = true;
      else
	program_name = argv[i];
    }

  while (fgets (buf, BUFSIZ, stdin))
    {
      remove_newline (buf);
      blanks_done = false;

      for (cp = buf; *cp; ++cp) ;

      while (cp != buf && *--cp == ' ') ;

      while (*cp == '.')
	{
	  join (cp + 1);
	  while (*cp)
	    ++cp;
	  while (*--cp == ' ') ;
	}

      for (cp = buf, indent = 0; *cp == ' ' || *cp == '\t'; ++cp)
	{
	  if (*cp == ' ')
	    indent++;
	  else
	    indent += 8;
	}

      if (!*cp)
	{			/* All blanks, possibly with "{" */
	  puts (buf);
	  continue;
	}
      if (*cp == '{')

        {
	  do_blanks (indent);
	  putchar ('{');
	  ++cp;
	  while (*cp == ' ' || *cp == '\t')
	    ++cp;
	  blanks_done = true;
	  if (!*cp)
	    {
	      putchar ('\n');
	      continue;
	    }
	}

      if (!blanks_done)
	do_blanks (indent);

      if (strncmp (cp, "read ( input", 12) == 0)
	{
	  char variable_name[20];
	  if (sscanf (cp, "read ( input , %s )", variable_name) != 1)
            {
  	      fprintf (stderr, "sscanf failed\n");
              uexit (1);
            }
	  printf ("%s = getint();\n", variable_name);
	  continue;
	}

      if (strncmp (cp, "lab", 3) == 0 && strchr (cp, ':'))
	{
	  do
	    {
	      putchar (*cp);
	    }
          while (*cp++ != ':');

          while (*cp == ' ')
	    ++cp;
	  putchar (' ');
	}

      if (strncmp (cp, "else write", 10) == 0)
	{
	  puts ("else");
	  do_blanks (indent);
	  cp += 5;
	  while (*cp == ' ')
	    ++cp;
	}

      if (bare (cp, '{'))
	{
	  while (*cp != '{')
	    {
	      putchar (*cp);
	      ++cp;
	    }
	  ++cp;
	  puts ("{");
	  indent += 4;
	  do_blanks (indent);
	  while (*cp == ' ')
	    ++cp;
	}

      if (strncmp (cp, "write (", 7) && strncmp (cp, "writeln (", 9))
	{
	  /* if not a write/writeln, just copy it to stdout and continue */
	  puts (cp);
	  continue;
	}
      cmd = cp;
      while (!whole (buf))	/* make sure we have whole stmt */
	{
	  fgets (&buf[strlen (buf)], BUFSIZ - strlen (buf), stdin);
	  remove_newline (buf);
	}

      while (*cp != '(')
	++cp;
      ++cp;
      while (*(cp + 1) == ' ')
	++cp;

      /* Some writes start with a variable, instead of a file. */
      if (*(cp + 1) == '"' || *(cp + 1) == '\''
          || strncmp (cp + 1, "buffer", 6) == 0
          || strncmp (cp + 1, "xchr", 4) == 0
          || strncmp (cp + 1, "k ,", 3) == 0
          || strncmp (cp + 1, "s ,", 3) == 0
          || strncmp (cp + 1, "dig", 3) == 0
          || strncmp (cp + 1, "HEX", 3) == 0
          || strncmp (cp + 1, "versionstring", 13) == 0
          || strncmp (cp + 1, "kpathseaversionstring", 21) == 0
         )
	strcpy (filename, "stdout");
      else
	{
	  file = filename;
	  while (*cp != ',' && *cp != ')')
	    *file++ = *cp++;
	  *file = '\0';
	}
      if (*cp == ')')
	{
	  printf ("putc%s ('\\n', %s);\n", oem, filename);
	  continue;
	}
      argp = ++cp;
      as = args;
      while (*cp == ' ')
	++cp;
      while (*cp != ')')
	{
	  if (*cp == '\'' || strncmp (cp, "xchr", 4) == 0
              || (strncmp (cp ,"HEX", 3) == 0
                  && (STREQ (program_name, "ofm2opl")
                      || STREQ (program_name, "opl2ofm")
                      || STREQ (program_name, "ovp2ovf")
                      || STREQ (program_name, "ovf2ovp")))
	      || strncmp (cp, "ASCII04", 7) == 0
	      || strncmp (cp, "ASCII1", 6) == 0
	      || strncmp (cp, "ASCIIall", 8) == 0              
	      || strncmp (cp, "months", 6) == 0
	      || strncmp (cp, "nameoffile", 10) == 0
	      || (strncmp (cp, "buffer", 6) == 0
                  && (STREQ (program_name, "vptovf")
                      || STREQ (program_name, "pltotf")
                      || STREQ (program_name, "ovp2ovf")
                      || STREQ (program_name, "ofm2opl")))
              || (((strncmp (cp, "buf", 3) == 0
		    || strncmp (cp, "xdig", 4) == 0
		    || strncmp (cp, "xext", 4) == 0
		    || strncmp (cp, "xhyf", 4) == 0)
                  && STREQ (program_name, "patgen")))
             )
	    {
	      *as++ = '%';
	      *as++ = 'c';
	      if (tex && strncmp (cp, "xchr", 4) == 0)
		{
		  *cp = 'X';
		  cp = strchr (cp, '[');
		  *cp = '(';
		  cp = advance_cp(cp,1);
		  *cp++ = ')';
		}
	      else if (*cp == '\'')
		cp += 2;
	    }
          
	  else if (*cp == '"')
	    {
	      *as++ = '%';
	      *as++ = 's';
	      while (*++cp != '"')	/* skip to end of string */
		if (*cp == '\\')
		  ++cp;		/* allow \" in string */
	    }

          /* More kludge -- versionstring is a string, not a number, so
             we have to use %s.  */
          else if (strncmp (cp, "versionstring", 13) == 0)
            {
              *as++ = '%';
              *as++ = 's';
            }

          else
	    {
	      *as++ = '%';
	      *as++ = 'l';
	      *as++ = 'd';
	      cp = insert_long (cp);
	      cp = skip_balanced (cp);	/* It's a numeric expression */
	    }
	  while (*cp != ',' && *cp != ')')
	    ++cp;
	  while (*cp == ',' || *cp == ' ')
	    ++cp;
	}

      if (strncmp (cmd, "writeln", 7) == 0)
	{
	  *as++ = '\\';
	  *as++ = 'n';
	}

      *as = '\0';
      if (strcmp (args, "%c") == 0)
	{
	  for (as = argp; *as; ++as) ;
	  while (*--as != ')') ;
	  *as = '\0';
	  printf ("putc%s (%s, %s);\n", oem, argp, filename);
	}
      else if (STREQ (args, "%s"))
        printf ("Fputs%s (%s, %s\n", oem, filename, argp);
      else
        printf ("fprintf%s (%s, \"%s\", %s\n", oem, filename, args, argp);
    }

  return EXIT_SUCCESS;
}
예제 #12
0
파일: NValue.cpp 프로젝트: DarkDare/voltdb
/**
 *   Set a decimal value from a serialized representation
 *   This function does not handle scientific notation string, Java planner should convert that to plan string first.
 */
void NValue::createDecimalFromString(const std::string &txt) {
    if (txt.length() == 0) {
        throw SQLException(SQLException::volt_decimal_serialization_error,
                                       "Empty string provided");
    }
    bool setSign = false;
    if (txt[0] == '-') {
        setSign = true;
    }

    /**
     * Check for invalid characters
     */
    for (int ii = (setSign ? 1 : 0); ii < static_cast<int>(txt.size()); ii++) {
        if ((txt[ii] < '0' || txt[ii] > '9') && txt[ii] != '.') {
            char message[4096];
            snprintf(message, 4096, "Invalid characters in decimal string: %s",
                     txt.c_str());
            throw SQLException(SQLException::volt_decimal_serialization_error,
                               message);
        }
    }

    std::size_t separatorPos = txt.find( '.', 0);
    if (separatorPos == std::string::npos) {
        const std::string wholeString = txt.substr( setSign ? 1 : 0, txt.size());
        const std::size_t wholeStringSize = wholeString.size();
        if (wholeStringSize > 26) {
            throw SQLException(SQLException::volt_decimal_serialization_error,
                               "Maximum precision exceeded. Maximum of 26 digits to the left of the decimal point");
        }
        TTInt whole(wholeString);
        if (setSign) {
            whole.SetSign();
        }
        whole *= kMaxScaleFactor;
        getDecimal() = whole;
        return;
    }

    if (txt.find( '.', separatorPos + 1) != std::string::npos) {
        throw SQLException(SQLException::volt_decimal_serialization_error,
                           "Too many decimal points");
    }

    const std::string wholeString = txt.substr( setSign ? 1 : 0, separatorPos - (setSign ? 1 : 0));
    const std::size_t wholeStringSize = wholeString.size();
    if (wholeStringSize > 26) {
        throw SQLException(SQLException::volt_decimal_serialization_error,
                           "Maximum precision exceeded. Maximum of 26 digits to the left of the decimal point");
    }
    TTInt whole(wholeString);
    std::string fractionalString = txt.substr( separatorPos + 1, txt.size() - (separatorPos + 1));
    // remove trailing zeros
    while (fractionalString.size() > 0 && fractionalString[fractionalString.size() - 1] == '0')
        fractionalString.erase(fractionalString.size() - 1, 1);
    // check if too many decimal places
    if (fractionalString.size() > 12) {
        throw SQLException(SQLException::volt_decimal_serialization_error,
                           "Maximum scale exceeded. Maximum of 12 digits to the right of the decimal point");
    }
    while(fractionalString.size() < NValue::kMaxDecScale) {
        fractionalString.push_back('0');
    }
    TTInt fractional(fractionalString);

    whole *= kMaxScaleFactor;
    whole += fractional;

    if (setSign) {
        whole.SetSign();
    }

    getDecimal() = whole;
}
예제 #13
0
//=============================================================================
Condition StreamTokenizer::tokenize(std::string& token)
{
  bool prev_overflow=m_overflow;
  m_overflow=false;
  int pre_skip=0;
  int token_len=0;
  int post_skip=0;

  bool found_token = next_token(m_buffer,pre_skip,token_len,post_skip);
  if (!found_token) {
    
    m_buffer.compact();
    int avail = m_buffer.free();
    if (avail==0) {
      m_overflow=true;
      token = std::string();
      return scx::Error;
    }

    int nr=0;
    Condition c = Stream::read(m_buffer.tail(),avail,nr);
    if (nr <= 0) {
      // No more bytes available from source
      token = std::string();
      return c;
    }
    m_buffer.push(nr);

    pre_skip=0;
    token_len=0;
    post_skip=0;
    found_token = next_token(m_buffer,pre_skip,token_len,post_skip);
    
    if (!found_token) {
      if (m_buffer.free() > 0) {
        // No more bytes available right now
        token = std::string();
        return scx::Wait;
      } else {
        // Buffer overflow
        m_overflow=true;
        token_len=m_buffer.used();
	return scx::Error;
      }
    }
  }

  if (m_line > 0) {
    // Perform line number tracking
    std::string whole((char*)m_buffer.head(),pre_skip + token_len + post_skip);
    std::string::size_type s = 0;
    while (true) {
      s = whole.find("\n",s);
      if (s == std::string::npos) {
	break;
      }
      ++s;
      ++m_line;
    }
  }

  token = std::string((char*)m_buffer.head()+pre_skip,token_len);
  m_buffer.pop(pre_skip+token_len+post_skip);

  if (prev_overflow) {
    if (found_token) {
      m_overflow=false;
    }
    return scx::Error;
  }

  return scx::Ok;  
}
예제 #14
0
void MeerkatNameHandler::request_finished(std::tr1::shared_ptr<HttpManager::HttpResponse> response,
        HttpManager::ERR_TYPE error, const boost::system::error_code& boost_error,
        std::tr1::shared_ptr<MetadataRequest> request, NameCallback callback) {

    std::tr1::shared_ptr<RemoteFileMetadata> bad;

    if (error == Transfer::HttpManager::REQUEST_PARSING_FAILED) {
        SILOG(transfer, error, "Request parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::RESPONSE_PARSING_FAILED) {
        SILOG(transfer, error, "Response parsing failed during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    } else if (error == Transfer::HttpManager::BOOST_ERROR) {
        SILOG(transfer, error, "A boost error happened during an HTTP name lookup (" << request->getURI() << "). Boost error = " << boost_error.message());
        callback(bad);
        return;
    } else if (error != HttpManager::SUCCESS) {
        SILOG(transfer, error, "An unknown error happened during an HTTP name lookup. (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getHeaders().size() == 0) {
        SILOG(transfer, error, "There were no headers returned during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    HttpManager::Headers::const_iterator it;
    it = response->getHeaders().find("Content-Length");
    if (it != response->getHeaders().end()) {
        SILOG(transfer, error, "Content-Length header was present when it shouldn't be during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    if (response->getStatusCode() != 200) {
        SILOG(transfer, error, "HTTP status code = " << response->getStatusCode() << " instead of 200 during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    it = response->getHeaders().find("File-Size");
    if (it == response->getHeaders().end()) {
        SILOG(transfer, error, "Expected File-Size header not present during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }
    std::string file_size_str = it->second;

    it = response->getHeaders().find("Hash");
    if (it == response->getHeaders().end()) {
        SILOG(transfer, error, "Expected Hash header not present during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }
    std::string hash = it->second;

    if (response->getData()) {
        SILOG(transfer, error, "Body present during an HTTP name lookup (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    Fingerprint fp;
    try {
        fp = Fingerprint::convertFromHex(hash);
    } catch(std::invalid_argument e) {
        SILOG(transfer, error, "Hash header didn't contain a valid Fingerprint string (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    std::istringstream istream(file_size_str);
    uint64 file_size;
    istream >> file_size;
    std::ostringstream ostream;
    ostream << file_size;
    if(ostream.str() != file_size_str) {
        SILOG(transfer, error, "Error converting File-Size header string to integer (" << request->getURI() << ")");
        callback(bad);
        return;
    }

    //Just treat everything as a single chunk for now
    Range whole(0, file_size, LENGTH, true);
    Chunk chunk(fp, whole);
    ChunkList chunkList;
    chunkList.push_back(chunk);

    std::tr1::shared_ptr<RemoteFileMetadata> met(new RemoteFileMetadata(fp, request->getURI(),
            file_size, chunkList, response->getRawHeaders()));

    callback(met);
    SILOG(transfer, detailed, "done http name handler request_finished");
}
예제 #15
0
파일: decimal.cpp 프로젝트: cs-wang/CLAIMS
bool Decimal::StrtoDecimal(int p, int s, const char *cp)
{
	bool		have_dp = false;
	int			i = 0;
    char decdigits[DECIMAL_MAXPRCISION+1];
	char num1[31];
    int dsign = DECIMAL_POS;
    int dweight = -1;
	const char *str = cp;
	
	memset(decdigits, '0', DECIMAL_MAXPRCISION+1);
	num1[0] = '1';
	memset(num1+1, '0', 30);
	
	while (isspace(*cp))
		cp++;
	//printf("source :%s\n",cp);
	switch (*cp)
	{
		case '+':
			cp++;
			break;
		case '-':
			dsign = DECIMAL_NEG;
			cp++;
			break;
	}

	while (*cp)
	{
		if (isdigit((unsigned char) *cp))
		{
			decdigits[i++] = *cp++;
			if (!have_dp)
				dweight++;
		}
		else if (*cp == '.')
		{
			if (have_dp)
			{
				printf("invalid input syntax for type numeric: \"%s\"\n", str);
				return false;
			}
			have_dp = true;
			cp++;
		}
		else
			break;
	}
	if (*cp == 'e' || *cp == 'E')
	{
		long		exponent;
		char	   *endptr;
		cp++;
		exponent = strtol(cp, &endptr, 10);
		if (endptr == cp)
		{
			printf("invalid input syntax for type numeric: \"%s\"\n", str);
			return false;
		}
		cp = endptr;
		dweight += (int) exponent;
	}
	if (dweight > p - s )
	{
		printf("invalid input syntax for type numeric: \"%s\"\n",	str);
		return false;
	}
	while (*cp)
	{
		if (isspace((unsigned char) *cp))
		{
			cp++;
		}
		else
		{
			printf("invalid input syntax for type numeric: \"%s\"\n",  str);
			return false;
		}
	}

	decdigits[DECIMAL_MAXSCALE + dweight + 1] = 0;
	char c = decdigits[s + dweight + 1];
	memset(decdigits + s + dweight + 1, '0', DECIMAL_MAXSCALE - s);
	TTInt whole(decdigits);
	
	num1[30 - s + 1] = 0;
	TTInt fra(num1);

	if (DECIMAL_NEG == dsign)
	{
		fra.SetSign();
		whole.SetSign();
	}
	SetTTInt((c>='5'?whole+fra:whole));	
	return true;
}
예제 #16
0
파일: NValue.cpp 프로젝트: AdvEnc/voltdb
/**
 *   Set a decimal value from a serialized representation
 *   This function does not handle scientific notation string, Java planner should convert that to plan string first.
 */
void NValue::createDecimalFromString(const std::string &txt) {
    if (txt.length() == 0) {
        throw SQLException(SQLException::volt_decimal_serialization_error,
                                       "Empty string provided");
    }
    bool setSign = false;
    if (txt[0] == '-') {
        setSign = true;
    }

    /**
     * Check for invalid characters
     */
    for (int ii = (setSign ? 1 : 0); ii < static_cast<int>(txt.size()); ii++) {
        if ((txt[ii] < '0' || txt[ii] > '9') && txt[ii] != '.') {
            char message[4096];
            snprintf(message, 4096, "Invalid characters in decimal string: %s",
                     txt.c_str());
            throw SQLException(SQLException::volt_decimal_serialization_error,
                               message);
        }
    }

    std::size_t separatorPos = txt.find( '.', 0);
    if (separatorPos == std::string::npos) {
        const std::string wholeString = txt.substr( setSign ? 1 : 0, txt.size());
        const std::size_t wholeStringSize = wholeString.size();
        if (wholeStringSize > 26) {
            throw SQLException(SQLException::volt_decimal_serialization_error,
                               "Maximum precision exceeded. Maximum of 26 digits to the left of the decimal point");
        }
        TTInt whole(wholeString);
        if (setSign) {
            whole.SetSign();
        }
        whole *= kMaxScaleFactor;
        getDecimal() = whole;
        return;
    }

    if (txt.find( '.', separatorPos + 1) != std::string::npos) {
        throw SQLException(SQLException::volt_decimal_serialization_error,
                           "Too many decimal points");
    }

    // This is set to 1 if we carry in the scale.
    int carryScale = 0;
    // This is set to 1 if we carry from the scale to the whole.
    int carryWhole = 0;

    // Start with the fractional part.  We need to
    // see if we need to carry from it first.
    std::string fractionalString = txt.substr( separatorPos + 1, txt.size() - (separatorPos + 1));
    // remove trailing zeros
    while (fractionalString.size() > 0 && fractionalString[fractionalString.size() - 1] == '0')
        fractionalString.erase(fractionalString.size() - 1, 1);
    //
    // If the scale is too large, then we will round
    // the number to the nearest 10**-12, and to the
    // furthest from zero if the number is equidistant
    // from the next highest and lowest.  This is the
    // definition of the Java rounding mode HALF_UP.
    //
    // At some point we will read a rounding mode from the
    // Java side at Engine configuration time, or something
    // like that, and have a whole flurry of rounding modes
    // here.  However, for now we have just the one.
    //
    if (fractionalString.size() > kMaxDecScale) {
        carryScale = ('5' <= fractionalString[kMaxDecScale]) ? 1 : 0;
        fractionalString = fractionalString.substr(0, kMaxDecScale);
    } else {
        while(fractionalString.size() < NValue::kMaxDecScale) {
            fractionalString.push_back('0');
        }
    }
    TTInt fractional(fractionalString);

    // If we decided to carry above, then do it here.
    // The fractional string is set up so that it represents
    // 1.0e-12 * units.
    fractional += carryScale;
    if (TTInt((uint64_t)kMaxScaleFactor) <= fractional) {
        // We know fractional was < kMaxScaleFactor before
        // we rounded, since fractional is 12 digits and
        // kMaxScaleFactor is 13.  So, if carrying makes
        // the fractional number too big, it must be eactly
        // too big.  That is to say, the rounded fractional
        // number number has become zero, and we need to
        // carry to the whole number.
        fractional = 0;
        carryWhole = 1;
    }

    // Process the whole number string.
    const std::string wholeString = txt.substr( setSign ? 1 : 0, separatorPos - (setSign ? 1 : 0));
    // We will check for oversize numbers below, so don't waste time
    // doing it now.
    TTInt whole(wholeString);
    whole += carryWhole;
    if (oversizeWholeDecimal(whole)) {
        throw SQLException(SQLException::volt_decimal_serialization_error,
                           "Maximum precision exceeded. Maximum of 26 digits to the left of the decimal point");
    }
    whole *= kMaxScaleFactor;
    whole += fractional;

    if (setSign) {
        whole.SetSign();
    }

    getDecimal() = whole;
}