LINUX.ORG.RU

История изменений

Исправление m0rph, (текущая версия) :

Если я правильно понял вопрос, то фактически тебе нужно определить наибольшую значимую цифру в числе и прибавить к ней единицу. Держи функцию из моей библиотечки. Реализацию mostSignificantBit приводить не буду, т.к. думаю ты все равно соптимизируешь ее через ассемблерную инструкцию или gcc'шный built-in. Реализацию я подсмотрел где-то в интернете и адаптировал под свои нужды, откуда взялась магическая константа 1233 уже не помню.

int mostSignificantDigit(uint64_t value)
{
	static const uint64_t kPowersOf10[] = {
		1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
		1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000,
		100000000000000, 1000000000000000, 10000000000000000,
		100000000000000000, 1000000000000000000, 10000000000000000000u
	};

	uint64_t temp = (mostSignificantBit(value) + 1) * 1233 >> 12;
	return temp - (value < kPowersOf10[temp]);
}

Исходная версия m0rph, :

Если я правильно понял вопрос, то фактически тебе нужно определить наибольшую значимую цифру в числе и прибавить к ней единицу. Держи функцию из моей библиотечки. Реализацию mostSignificantBit приводить не буду, т.к. думаю ты все равно соптимизируешь ее через ассемблерную инструкцию или gcc'шный built-in. Реализацию я подсмотрел где-то в интернете и адаптировал под свои нужды, откуда взялась магическая константа 1233 уже не помню.

template<typename T>
typename std::enable_if<std::is_integral<T>::value, int>::type
mostSignificantDigit(T value)
{
	static const uint64_t powersOf10[] = {
		1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
		1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000,
		100000000000000, 1000000000000000, 10000000000000000,
		100000000000000000, 1000000000000000000, 10000000000000000000u
	};

	uint64_t temp = (mostSignificantBit(value) + 1) * 1233 >> 12;
	return temp - (value < powersOf10[temp]);
}