#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <chrono>
static int log10_1(unsigned int num)
{
int ret;
static_assert(sizeof(num) == 4, "expected 32-bit long");
if (num >= 10000)
{
if (num >= 1000000)
{
if (num >= 100000000)
ret = (num >= 1000000000) ? 10 : 9;
else
ret = (num >= 10000000) ? 8 : 7;
}
else
ret = (num >= 100000) ? 6 : 5;
}
else
{
if (num >= 100)
ret = num >= 1000 ? 4 : 3;
else
ret = num >= 10 ? 2 : 1;
}
return ret;
}
// write string representation of number `n` into buf and return pointer to terminating null
char* to_str(char* buf, unsigned int n)
{
static const char dig_[] = "0001020304050607080910111213141516171819"
"20212223242526272829303132333435363738394041424344454647484950515253545556575859"
"60616263646566676869707172737475767778798081828384858687888990919293949596979899";
int len = log10_1(n);
char *p = buf + len;
*p-- = 0;
while (n >= 100)
{
unsigned int x = (n % 100) * 2;
n /= 100;
*p-- = dig_[x + 1];
*p-- = dig_[x];
}
if (n >= 10)
{
unsigned int x = n * 2;
*p-- = dig_[x + 1];
*p-- = dig_[x];
}
else
*p-- = (char)('0' + n);
return buf + len;
}
// write string representation of number `n` into buf and return pointer to terminating null
char* to_str(char* buf, long n)
{
unsigned int l;
if (n < 0)
{
*buf++ = '-';
l = (unsigned int)(-n);
}
else
l = (unsigned int)n;
return to_str(buf, l);
}
template <typename T>
void foo(char *buffer, T value)
{
static_assert(std::is_integral<T>::value, "Type of value must be an integral type");
if (value < 0) {
*(buffer++) = '-';
}
char *start = buffer;
while (value != 0) {
*(buffer++) = '0' + std::abs(value % 10);
value /= 10;
}
if (buffer == start) {
*(buffer++) = '0';
}
else {
std::reverse(start, buffer);
}
*buffer = '\0';
}
int main()
{
long ll[3000];
for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
ll[i] = (rand() << 16) | rand() * (rand() > 10000 ? -1 : 1);
char buf1[32], buf2[32], buf3[32];
for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
{
foo(buf1, ll[i]);
to_str(buf2, ll[i]);
sprintf(buf3, "%d", ll[i]);
if (strcmp(buf1, buf2) || strcmp(buf1, buf3))
printf("error!\n");
}
auto start1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; ++i)
{
for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
foo(buf1, ll[i]);
} auto finish1 = std::chrono::high_resolution_clock::now();
auto start2 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; ++i)
{
for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
to_str(buf2, ll[i]);
}
auto finish2 = std::chrono::high_resolution_clock::now();
auto start3 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 10000; ++i)
{
for (int i = 0; i < sizeof(ll) / sizeof(ll[0]); ++i)
sprintf(buf3, "%d", ll[i]);
}
auto finish3 = std::chrono::high_resolution_clock::now();
long long micro1 = std::chrono::duration_cast<std::chrono::milliseconds>(finish1 - start1).count();
long long micro2 = std::chrono::duration_cast<std::chrono::milliseconds>(finish2 - start2).count();
long long micro3 = std::chrono::duration_cast<std::chrono::milliseconds>(finish3 - start3).count();
printf("foo time: %lld ms\n", micro1);
printf("to_str time: %lld ms\n", micro2);
printf("sprintf time: %lld ms\n", micro3);
}