C++ 确定整数位数的有效方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1489830/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Efficient way to determine number of digits in an integer
提问by Seth
What is a very efficientway of determining how many digits there are in an integer in C++?
在 C++ 中确定整数中有多少位的非常有效的方法是什么?
采纳答案by Vitali
Well, the most efficient way, presuming you know the size of the integer, would be a lookup. Should be faster than the much shorter logarithm based approach. If you don't care about counting the '-', remove the + 1.
好吧,假设您知道整数的大小,最有效的方法是查找。应该比更短的基于对数的方法快。如果您不关心计算“-”,请删除 + 1。
// generic solution
template <class T>
int numDigits(T number)
{
int digits = 0;
if (number < 0) digits = 1; // remove this line if '-' counts as a digit
while (number) {
number /= 10;
digits++;
}
return digits;
}
// partial specialization optimization for 32-bit numbers
template<>
int numDigits(int32_t x)
{
if (x == MIN_INT) return 10 + 1;
if (x < 0) return numDigits(-x) + 1;
if (x >= 10000) {
if (x >= 10000000) {
if (x >= 100000000) {
if (x >= 1000000000)
return 10;
return 9;
}
return 8;
}
if (x >= 100000) {
if (x >= 1000000)
return 7;
return 6;
}
return 5;
}
if (x >= 100) {
if (x >= 1000)
return 4;
return 3;
}
if (x >= 10)
return 2;
return 1;
}
// partial-specialization optimization for 8-bit numbers
template <>
int numDigits(char n)
{
// if you have the time, replace this with a static initialization to avoid
// the initial overhead & unnecessary branch
static char x[256] = {0};
if (x[0] == 0) {
for (char c = 1; c != 0; c++)
x[c] = numDigits((int32_t)c);
x[0] = 1;
}
return x[n];
}
回答by Skizz
The simplest way is to do:
最简单的方法是:
unsigned GetNumberOfDigits (unsigned i)
{
return i > 0 ? (int) log10 ((double) i) + 1 : 1;
}
log10 is defined in <cmath>
or <math.h>
. You'd need to profile this to see if it's faster than any of the others posted here. I'm not sure how robust this is with regards to float point precision. Also, the argument is unsigned as negative values and log don't really mix.
log10 在<cmath>
或 中定义<math.h>
。您需要对此进行概要分析,以查看它是否比此处发布的任何其他文件都快。我不确定这在浮点精度方面有多强大。此外,该参数是无符号的,因为负值和 log 并没有真正混合。
回答by Brad
Perhaps I misunderstood the question but doesn't this do it?
也许我误解了这个问题,但这不是吗?
int NumDigits(int x)
{
x = abs(x);
return (x < 10 ? 1 :
(x < 100 ? 2 :
(x < 1000 ? 3 :
(x < 10000 ? 4 :
(x < 100000 ? 5 :
(x < 1000000 ? 6 :
(x < 10000000 ? 7 :
(x < 100000000 ? 8 :
(x < 1000000000 ? 9 :
10)))))))));
}
回答by squelart
int digits = 0; while (number != 0) { number /= 10; digits++; }
Note: "0" will have 0 digits! If you need 0 to appear to have 1 digit, use:
注意:“0”将有 0 位数字!如果您需要 0 显示为 1 位数,请使用:
int digits = 0; do { number /= 10; digits++; } while (number != 0);
(Thanks Kevin Fegan)
(感谢凯文·费根)
In the end, use a profiler to know which of all the answers here will be faster on your machine...
最后,使用分析器来了解这里所有答案中的哪一个在您的机器上会更快......
回答by blinnov.com
Practical joke: This is themost efficient way (number of digits is calculated at compile-time):
恶作剧:这是在最有效的方式(中位数在编译时计算):
template <unsigned long long N, size_t base=10>
struct numberlength
{
enum { value = 1 + numberlength<N/base, base>::value };
};
template <size_t base>
struct numberlength<0, base>
{
enum { value = 0 };
};
May be useful to determine the width required for number field in formatting, input elements etc.
可能有助于确定格式、输入元素等中数字字段所需的宽度。
回答by Josh Haberman
See Bit Twiddling Hacksfor a much shorter version of the answer you accepted. It also has the benefit of finding the answer sooner if your input is normally distributed, by checking the big constants first. (v >= 1000000000)
catches 76% of the values, so checking that first will on average be faster.
有关您接受的答案的更短版本,请参阅Bit Twiddling Hacks。如果您的输入是正态分布的,通过首先检查大常数,它还有一个好处是可以更快地找到答案。 (v >= 1000000000)
捕获 76% 的值,因此首先检查平均会更快。
回答by wugoat
convert to string and then use built-in functions
转换为字符串,然后使用内置函数
unsigned int i;
cout<< to_string(i).length()<<endl;
回答by bemaru
int x = 1000;
int numberOfDigits = x ? static_cast<int>(log10(abs(x))) + 1 : 1;
回答by bemaru
The ppc architecture has a bit counting instruction. With that, you can determine the log base 2 of a positive integer in a single instruction. For example, 32 bit would be:
ppc 架构有一个比特计数指令。有了它,您可以在单个指令中确定正整数的对数基数 2。例如,32 位将是:
#define log_2_32_ppc(x) (31-__cntlzw(x))
If you can handle a small margin of error on large values you can convert that to log base 10 with another few instructions:
如果您可以处理大值的小误差,您可以使用其他几条指令将其转换为以 10 为底的日志:
#define log_10_estimate_32_ppc(x) (9-(((__cntlzw(x)*1233)+1545)>>12))
This is platform specific and slightly inaccurate, but also involves no branches, division or conversion to floating point. All depends on what you need.
这是特定于平台的并且稍微不准确,但也不涉及分支、除法或转换为浮点。一切都取决于你需要什么。
I only know the ppc instructions off hand, but other architectures should have similar instructions.
我只知道手头的 ppc 指令,但其他架构应该有类似的指令。
回答by Ira Baxter
A previous poster suggested a loop that divides by 10. Since multiplies on modern machines are a lot faster, I'd recommend the following code instead:
之前的一张海报提出了一个除以 10 的循环。由于现代机器上的乘法要快得多,我建议改为使用以下代码:
int digits = 1, pten=10; while ( pten <= number ) { digits++; pten*=10; }