Beispiel #1
0
char * Parser::DoubleToString(double value)
{
	int decimal, sign;
	char* res = (char*)heap_my.get_mem(_CVTBUFSIZE);
	int buf = _ecvt_s(res, _CVTBUFSIZE, value, 100, &decimal, &sign);
	if (buf != 0)
		return nullptr;
	return res;
}
int _tmain(int argc, _TCHAR* argv[])
{
	size_t max_num = 100000000;
	const int max_char_per_float = 10;
	const size_t buffer_element_count = 100000;
	size_t buffer_byte_size = buffer_element_count * (max_char_per_float + 5);
	char* write_buffer = new char[buffer_byte_size];
	HANDLE hFile = ::CreateFile(L"output.txt", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, NULL);
	// std::ofstream output();
	for (size_t i=0; i < max_num / buffer_element_count; ++i) 
	{
		int buffer_position = 0;
		for (int k = 0; k < buffer_element_count; ++k)
		{
			char number_buffer[32];
			int pos = 0;
			int dec;
			int sign;
			float random = float(rand()) / RAND_MAX;
			_ecvt_s(number_buffer, random, max_char_per_float, &dec, &sign);
			if (sign)
			{
				write_buffer[buffer_position++] = '-';
			}
			while(pos<dec) 
			{ 
				write_buffer[buffer_position++] = number_buffer[pos++]; 
			}
			write_buffer[buffer_position++] = '.';
			while (number_buffer[pos])
			{
				write_buffer[buffer_position++] = number_buffer[pos++];
			}
			write_buffer[buffer_position++] = '\r';
			write_buffer[buffer_position++] = '\n';
		}
		DWORD bytes_written = 0;
		::WriteFile(hFile, write_buffer, buffer_position, &bytes_written, NULL);
	}

	::CloseHandle(hFile);
	return 0;
}
Beispiel #3
0
    void print(double val, buffered_ostream<CharT>& os)
    {
        char buf[_CVTBUFSIZE];
        int decimal_point = 0;
        int sign = 0;

        if (precision_ >= _CVTBUFSIZE)
        {
            precision_ = _CVTBUFSIZE - 1;
        }

        int err = _ecvt_s(buf, _CVTBUFSIZE, val, precision_, &decimal_point, &sign);
        if (err != 0)
        {
            throw std::runtime_error("Failed attempting double to string conversion");
        }
        char* s = buf;
        char* se = s + precision_;

        int i, k;
        int j;

        if (sign)
        {
            os.put('-');
        }
        if (decimal_point <= -4 || decimal_point > se - s + 5) 
        {
            os.put(*s++);
            if (s < se) 
            {
                os.put('.');
                while ((se-1) > s && *(se-1) == '0')
                {
                    --se;
                }

                while(s < se)
                {
                    os.put(*s++);
                }
            }
            os.put('e');
            /* sprintf(b, "%+.2d", decimal_point - 1); */
            if (--decimal_point < 0) {
                os.put('-');
                decimal_point = -decimal_point;
                }
            else
                os.put('+');
            for(j = 2, k = 10; 10*k <= decimal_point; j++, k *= 10);
            for(;;) 
            {
                i = decimal_point / k;
                os.put(i + '0');
                if (--j <= 0)
                    break;
                decimal_point -= i*k;
                decimal_point *= 10;
            }
        }
        else if (decimal_point <= 0) 
        {
            os.put('0');
            os.put('.');
            while ((se-1) > s && *(se-1) == '0')
            {
                --se;
            }
            for(; decimal_point < 0; decimal_point++)
            {
                os.put('0');
            }
            while(s < se)
            {
                os.put(*s++);
            }
        }
        else {
            while(s < se) 
            {
                os.put(*s++);
                if ((--decimal_point == 0) && s < se)
                {
                    os.put('.');
                    while ((se-1) > s && *(se-1) == '0')
                    {
                        --se;
                    }
                }
            }
            for(; decimal_point > 0; decimal_point--)
            {
                os.put('0');
            }
        }
    }
int _tmain(int argc, _TCHAR* argv[])
{
	const size_t max_num = 100000000;
	const int buffer_element_count = 10000;
	const int max_float_digits = 10;
	
	// Init critical section;
	InitializeCriticalSection(&g_write_queue_cs);

	HANDLE hFile = ::CreateFile(L"output.txt", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, NULL);
	if (hFile == INVALID_HANDLE_VALUE) 
	{
		printf("Oppps");
		exit(-1);
	}

	// Launch a writer thread.
	HANDLE hThread = CreateThread(NULL, 0, &WriteThreadProc, hFile,0, 0);

	// std::ofstream output();
	for (size_t i=0; i < max_num / buffer_element_count; ++i) 
	{
		// Prepare a block of numbers for writing.
		WriteBuffer* write_buffer = new WriteBuffer(buffer_element_count, max_float_digits);
		char* write_ptr = write_buffer->ptr_;
		for (int k = 0; k < buffer_element_count; ++k)
		{
			// Format each float to string and append to buffer.
			char number_micro_buffer[32];
			int pos = 0;
			int dec;
			int sign;
			float random = float(rand()) / RAND_MAX;
			_ecvt_s(number_micro_buffer, random, max_float_digits, &dec, &sign);

			if (sign)
			{
				*(write_ptr++) = '-';
			}
			if (dec <=0) {
				*(write_ptr++) = '0';
			}
			while(pos<dec) 
			{ 
				*(write_ptr++) = number_micro_buffer[pos++]; 
			}
			*(write_ptr++) = '.';
			while (number_micro_buffer[pos])
			{
				*(write_ptr++) = number_micro_buffer[pos++];
			}
			*(write_ptr++) = '\r';
			*(write_ptr++) = '\n';
		}
		// Compute how many bytes to write.
		write_buffer->useful_data_size_ = write_ptr - write_buffer->ptr_;

		// Enqueue for writing.
		EnterCriticalSection(&g_write_queue_cs);
		g_write_queue.push(write_buffer);
		LeaveCriticalSection(&g_write_queue_cs);
	}

	g_done = true;
	WaitForSingleObject(hThread, INFINITE);

	::CloseHandle(hFile);
	return 0;
}
char *
dtoa(double d,       // IN
     int mode,       // IN
     int prec,       // IN
     int *expOut,    // OUT
     int *sign,      // OUT
     char **strEnd)  // OUT
{
   char *str = NULL;
   int dec;

#if defined(_WIN32)
   if (2 == mode) {
      str = malloc(_CVTBUFSIZE);
      if (str) {
         if (_ecvt_s(str, _CVTBUFSIZE, d, prec, &dec, sign)) {
            free(str);
            str = NULL;
         }
      }
   } else {
      ASSERT(3 == mode);
      str = malloc(_CVTBUFSIZE);
      if (str) {
         if (_fcvt_s(str, _CVTBUFSIZE, d, prec, &dec, sign)) {
            free(str);
            str = NULL;
         }
      }

      /*
       * When the value is not zero but rounds to zero at prec digits,
       * the Windows fcvt() sometimes returns the empty string and
       * a negative dec that goes too far (as in -dec > prec).
       * For example, converting 0.001 with prec 1 results in
       * the empty string and dec -2.  (See bug 253674.)
       *
       * We just clamp dec to -prec when this happens.
       *
       * While this may appear to be a safe and good thing to
       * do in general.  It really only works when the result is
       * all zeros or empty.  Since checking for all zeros is
       * expensive, we only check for empty string, which works
       * for this bug.
       */

      if (str && *str == '\0' && dec < 0 && dec < -prec) {
	 dec = -prec;
      }
   }
#else // _WIN32
   static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

   if (2 == mode) {
      pthread_mutex_lock(&mutex);
      str = strdup(ecvt(d, prec, &dec, sign));
      pthread_mutex_unlock(&mutex);
   } else {
      ASSERT(3 == mode);

#ifdef __APPLE__
      /*
       * The Mac fcvt() returns "" when prec is 0, so we have to
       * compensate.  See bug 233530.
       * While it is conceivable that fcvt(round(d), 1) can return
       * a string that doesn't end in 0, it doesn't seem to happen
       * in practice (on the Mac).  The problematic case that we
       * want to avoid is a last digit greater than 4, which requires
       * rounding up, which we don't want to do, which is why we're
       * doing the rounding on the number instead of after fcvt()
       * in the first place.
       * -- edward
       */

      if (prec == 0) {
	 size_t l;
         pthread_mutex_lock(&mutex);
	 str = strdup(fcvt(round(d), 1, &dec, sign));
         pthread_mutex_unlock(&mutex);
	 if (str) {
	    l = strlen(str);
	    ASSERT(l > 0);
	    l--;
	    ASSERT(str[l] == '0');
	    str[l] = '\0';
         }
      } else 
#endif // __APPLE__
      {
         pthread_mutex_lock(&mutex);
         str = strdup(fcvt(d, prec, &dec, sign));
         pthread_mutex_unlock(&mutex);
      }
   }
#endif // _WIN32

   if (str) {
      *strEnd = str + strlen(str);

      /* strip trailing zeroes */
      while ((*strEnd > str) && ('0' == *((*strEnd) - 1))) {
         (*strEnd)--;
      }

      *expOut = dec;
   }

   return str;
}
std::basic_string<Char> float_to_string(double val, size_t precision)
{
    std::basic_string<Char> s;
    char buf[_CVTBUFSIZE];
    int decimal_point = 0;
    int sign = 0;

    if (precision >= _CVTBUFSIZE)
    {
        precision = _CVTBUFSIZE - 1;
    }

    int err = _ecvt_s(buf, _CVTBUFSIZE, val, static_cast<int>(precision), &decimal_point, &sign);
    if (err != 0)
    {
        throw std::runtime_error("Failed attempting double to string conversion");
    }
    if (sign != 0)
    {
        s.push_back('-');
    }

    int len = static_cast<int>(precision);

    int decimal;
    int exponent;
    if (decimal_point < 0 || decimal_point > len)
    {
        decimal = 1;
        exponent = decimal_point - 1;
    }
    else
    {
        decimal = decimal_point;
        exponent = 0;
    }

    while (len >= 2 && buf[len - 1] == '0' && (len - 1) != decimal)
    {
        --len;
    }

    if (decimal == 0)
    {
        s.push_back('0');
        s.push_back('.');
    }
    s.push_back(buf[0]);
    for (int i = 1; i < len; ++i)
    {
        if (i == decimal)
        {
            s.push_back('.');
        }
        s.push_back(buf[i]);
    }
    if (exponent != 0)
    {
        s.push_back('e');
        if (exponent > 0)
        {
            s.push_back('+');
        }
        int err2 = _itoa_s(exponent,buf,_CVTBUFSIZE,10);
        if (err2 != 0)
        {
            throw std::runtime_error("Failed attempting double to string conversion");
        }
        for (int i = 0; i < _CVTBUFSIZE && buf[i]; ++i)
        {
            s.push_back(buf[i]);
        }
    }
    return s;
}