当前位置:编程学习 > C#/ASP.NET >>

一个整数,如何高效率地取个位上的数

或者十位,或者百位,或者N位上的数 --------------------编程问答-------------------- Int32 i= 12234;
String s = i.ToString();

通过s[j] --------------------编程问答-------------------- 如果一次只取一个,那直接乘除运算好了。
如果一次要取每个位,就转字符串再处理了。 --------------------编程问答--------------------

Tostring().Substring(n-1,1);
--------------------编程问答-------------------- %100,%10... --------------------编程问答-------------------- 取余,如  102456116%10 --------------------编程问答--------------------
引用 5 楼 mngzilin 的回复:
取余,如  102456116%10


五楼正解 --------------------编程问答--------------------
引用 2 楼 wuyazhe 的回复:
如果一次只取一个,那直接乘除运算好了。
如果一次要取每个位,就转字符串再处理了。


无疑乘除是效率最高的 --------------------编程问答--------------------
int n = 123456;
Console.WriteLine((n- n / 10* 10).ToString());
--------------------编程问答-------------------- 谁知道楼主到底想啥,如果说每位都要,一次性要个位、十位、百位……
那不要反复乘除…… --------------------编程问答--------------------
引用 9 楼 wuyazhe 的回复:
谁知道楼主到底想啥,如果说每位都要,一次性要个位、十位、百位……
那不要反复乘除……


引用楼主 bidaas 的回复:
或者十位,或者百位,或者N位上的数

楼主说的是或者啊,显然是只要一位

如果是要十位上的数,我8楼的答案那个数先除以10即可,百位除以100,依此类推 --------------------编程问答-------------------- 用字符串处理。 --------------------编程问答-------------------- 可以用字符串处理比较好 --------------------编程问答-------------------- 取余,也就是模10运算应该是最好的。 --------------------编程问答-------------------- 看来懂计算机原理的人很少啊,难道都不是学计算机的?
还是没看到楼主的高效率三个字?
乘除虽然不如加减快,更比为运算慢得多,但还是基本的运算
而一个二进制数转为一个十进制字符串恐怕是一系列比较复杂的操作~ --------------------编程问答--------------------
引用 3 楼 wangkun9999 的回复:
C# code

Tostring().Substring(n-1,1);


赞同 --------------------编程问答-------------------- int n = 12345;
int i = 2;
int t = n / Math.Power(10, i-1);  //去尾
int r = t % 10; //取最后一位 --------------------编程问答--------------------
引用 14 楼 viena 的回复:
看来懂计算机原理的人很少啊,难道都不是学计算机的?
还是没看到楼主的高效率三个字?
乘除虽然不如加减快,更比为运算慢得多,但还是基本的运算
而一个二进制数转为一个十进制字符串恐怕是一系列比较复杂的操作~


哈哈,VMM现身了。怎么感觉你就是一个“不懂装懂”的回贴人啊。 --------------------编程问答-------------------- 测了一下,花费是字符串时间的1/6左右

        /// <summary>
        /// 求num在n位上的数字
        /// </summary>
        /// <param name="num">正整数</param>
        /// <param name="n">所求数字位置</param>
        int findIt(int num, int n)
        {

            int power = 1;
            for (int i = 0; i < n; i++)
            {
                power *= 10;
            }
            return (num - num / power * power) * 10 / power;
        }
--------------------编程问答--------------------
引用 17 楼 gsdn00a 的回复:
引用 14 楼 viena 的回复:
看来懂计算机原理的人很少啊,难道都不是学计算机的?
还是没看到楼主的高效率三个字?
乘除虽然不如加减快,更比为运算慢得多,但还是基本的运算
而一个二进制数转为一个十进制字符串恐怕是一系列比较复杂的操作~


哈哈,VMM现身了。怎么感觉你就是一个“不懂装懂”的回贴人啊。


请指教 --------------------编程问答--------------------
引用 19 楼 viena 的回复:
请指教


在VMM失误时,开个玩笑。 :)

上面的方法中,5楼效率最高。

private void button1_Click(object sender, EventArgs e)
{
    int m, n = 123456;

    DateTime dt1 = DateTime.Now;
    
    for (int i = 0; i < 100000000; i++)
    {
         m = n - n / 10 * 10;
    }
    
    DateTime dt2 = DateTime.Now;

    for (int i = 0; i < 100000000; i++)
    {
         m = n % 10;
    }
    
    DateTime dt3 = DateTime.Now;

    MessageBox.Show((dt2 - dt1).Milliseconds.ToString());  // 868
    MessageBox.Show((dt3 - dt2).Milliseconds.ToString());  // 765
}
--------------------编程问答-------------------- vmm是说我呢,GSDN00A你需要增强中文理解能力,他只是说和转换成字符后,再取对应的位,和用数字乘除相比。你就钻牛角尖不看人家说话的重点。5楼的是快,vmm是说我回复的那个。 --------------------编程问答--------------------
private void button1_Click(object sender, EventArgs e)
{
    int m;

    int tick = Environment.TickCount;

    int times = 100000000;
    for (int i = 0; i < times; i++)
    {
        m = 102456116 - 102456116 / 10 * 10;
    }
    tick = Environment.TickCount - tick;

    int tick2 = Environment.TickCount;
    for (int i = 0; i < times; i++)
    {
        m = 102456116 % 10;
    }
    tick2 = Environment.TickCount - tick2;

    MessageBox.Show(tick.ToString());  // 281
    MessageBox.Show(tick2.ToString());  // 282

}
--------------------编程问答-------------------- 直接取余未必快啊,怎么我这里测试的结果是相反的呢?
乘除耗时:00:00:00.5236724
取余耗时:00:00:00.5544903
我是每次取不同的数,你们的是取相同的数

    class Program
    {

        static Stopwatch watch = new Stopwatch();
        static Stopwatch watch2 = new Stopwatch();
        static void Main( string[] args )
        {
            int m,n;

            watch2.Start();
            for (int i = 100000; i < 100000000; i++)
            {
                //n = i / 10;
                n = i;
                m = n - n / 10 * 10;
            }
            watch2.Stop();
            Console.WriteLine("乘除耗时: {0}", watch2.Elapsed);

            watch.Start();
            for (int i = 100000; i < 100000000; i++)
            {
                //n = i / 10;
                n = i;
                m = n % 10;
            }
            watch.Stop();
            Console.WriteLine("取余耗时: {0}", watch.Elapsed);

            GC.Collect();
            Console.ReadLine();
        }
--------------------编程问答-------------------- 如果取第i位数
如果去个位数
n%=10;
其他位数
n%=10^(i+1);
n/=10^(i-1); --------------------编程问答--------------------
引用 21 楼 wuyazhe 的回复:
GSDN00A你需要增强中文理解能力。


兄弟,没感觉出来是开玩笑吗? VMM的实力有目共睹,不用我们为其辩护。


兄弟,你在22楼贴上了一个错误的测试用例,结果是随机的,不能证明任何问题。原因吗?你现在应该知道为什么了。

哈哈,是否说明你是一个“不懂装懂”的回贴人? 看了阿非宣传的“知不知”理论,不敢回贴了  :)

--------------------编程问答-------------------- 根据阿非宣传的“知不知”理论,证明.net新旧斑竹是“不懂装懂”的回贴人。 --------------------编程问答--------------------
引用 26 楼 gsdn00a 的回复:
根据阿非宣传的“知不知”理论,证明.net新旧斑竹是“不懂装懂”的回贴人。


IL是我的软肋,我没说我理解这其中曲直,只是把你贴的例子测试,并没有你贴的结果那么明显,并且我尝试用常量来替换后,得到结果是和你的不同,对IL这层我的确不懂,我只是用我测试的结果来说,你可以说任何一个人不懂装懂,这个都成立,所有人都有不懂的地方。这句话只说明了你讨论问题时候喜欢人身攻击而不是讨论问题本身。这类话题到此为止,那谁了解IL,帮我解释一下使用变量和不使用变量,为什么生成的IL会差别这么大把。实在没看明白。
code1:

int m;
int times = 100000000;
for (int i = 0; i < times; i++)
{
    m = 102456116 - 102456116 / 10 * 10;
}

对应IL

L_000c: stloc.1 
L_000d: ldc.i4 0x5f5e100
L_0012: stloc.2 
L_0013: ldc.i4.0 
L_0014: stloc.3 
L_0015: br.s L_001f
L_0017: nop 
L_0018: ldc.i4.6 
L_0019: stloc.0 
L_001a: nop 
L_001b: ldloc.3 
L_001c: ldc.i4.1 
L_001d: add 
L_001e: stloc.3 
L_001f: ldloc.3 
L_0020: ldloc.2 
L_0021: clt 
L_0023: stloc.s CS$4$0000
L_0025: ldloc.s CS$4$0000
L_0027: brtrue.s L_0017


int m = 102456116;
int times = 100000000;
for (int i = 0; i < times; i++)
{
    m = m - m / 10 * 10;
}


L_000c: stloc.1 
L_000d: ldc.i4 0x5f5e100
L_0012: stloc.2 
L_0013: ldc.i4.0 
L_0014: stloc.3 
L_0015: br.s L_0027
L_0017: nop 
L_0018: ldloc.0 
L_0019: ldloc.0 
L_001a: ldc.i4.s 10
L_001c: div 
L_001d: ldc.i4.s 10
L_001f: mul 
L_0020: sub 
L_0021: stloc.0 
L_0022: nop 
L_0023: ldloc.3 
L_0024: ldc.i4.1 
L_0025: add 
L_0026: stloc.3 
L_0027: ldloc.3 
L_0028: ldloc.2 
L_0029: clt 
L_002b: stloc.s CS$4$0000
L_002d: ldloc.s CS$4$0000
L_002f: brtrue.s L_0017
--------------------编程问答--------------------
引用 27 楼 wuyazhe 的回复:
引用 26 楼 gsdn00a 的回复:
根据阿非宣传的“知不知”理论,证明.net新旧斑竹是“不懂装懂”的回贴人。


IL是我的软肋,我没说我理解这其中曲直,只是把你贴的例子测试,并没有你贴的结果那么明显,并且我尝试用常量来替换后,得到结果是和你的不同,对IL这层我的确不懂,我只是用我测试的结果来说,你可以说任何一个人不懂装懂,这个都成立,所有人都有不懂的地方。这句话只说明了你讨论问……

使用变量有一个取值并且赋值的过程,而直接使用常量则没有这个过程。 --------------------编程问答-------------------- 位操作效率最高了

%10 --------------------编程问答-------------------- 对于一个整数的处理,不管怎么处理效率都不会太低~~ --------------------编程问答-------------------- 知道的方法都被说了
不知道的也有很多~mark学习 --------------------编程问答-------------------- 悲剧  一眼扫下来都没看懂  不知道楼上做的比较和楼主问题有啥关系
谁给我说说?
n=1346436457,取百万位上的数,楼上的方法怎么做呢?
(n%10000000)/1000000 --------------------编程问答-------------------- 真比较 n - n / 10 * 10和  n%10速度谁快
光做测试怎么行啊?CPU温度变化都有影响
直接看汇编代码好了
--------------------编程问答-------------------- 好贴!  移位不知可以不可以 --------------------编程问答--------------------
引用 33 楼 cqsfd 的回复:
真比较 n - n / 10 * 10和 n%10速度谁快
光做测试怎么行啊?CPU温度变化都有影响
直接看汇编代码好了


在我的机器上,改变先后顺序、改变循环上下界,n次运行的结果都是一致的:
那就是 n-n/10*10 比 n%10 快

另外,取百万位的数只要先除以一百万即可,没有问题的 --------------------编程问答-------------------- 直接去余应该比较快吧 --------------------编程问答--------------------
引用 29 楼 teng_s2000 的回复:
位操作效率最高了

%10


引用 34 楼 foxdave 的回复:
好贴!  移位不知可以不可以


位操作貌似在这里派不上用场
因为这是取十进制的位而不是二进制
计算机里的数字都是二进制
十进制只是一个逻辑概念
29楼,取余与位操作不搭界吧 --------------------编程问答--------------------
引用 36 楼 langyue555 的回复:
直接去余应该比较快吧


你可以拿我的控制台测试代码去运行下看看 --------------------编程问答-------------------- 整型在内存是如何存的?如果知道规则,用位运算取就可以了, 比如8421 --------------------编程问答--------------------
引用 35 楼 viena 的回复:
引用 33 楼 cqsfd 的回复:
真比较 n - n / 10 * 10和 n%10速度谁快
光做测试怎么行啊?CPU温度变化都有影响
直接看汇编代码好了

另外,取百万位的数只要先除以一百万即可,没有问题的


你的公式只是找到余数而已,除以1百万
n=1346436457
 n - n / 1000000 * 1000000 = 436457
(n%10000000)/1000000  取个余再除  我们应该想办法找到比这个更快的呀 --------------------编程问答--------------------
火药十足,目前我的经验是:1分钟内出数据客户是可以忍受的。。。。O(∩_∩)O~ --------------------编程问答-------------------- 而不应该纠结在如何取余数吧? --------------------编程问答-------------------- 学习! --------------------编程问答--------------------
引用 40 楼 cqsfd 的回复:
你的公式只是找到余数而已,除以1百万
n=1346436457
 n - n / 1000000 * 1000000 = 436457
(n%10000000)/1000000 取个余再除 我们应该想办法找到比这个更快的呀

不是这个意思,1346436457除以1000000得1346,然后1346就可以用取个位的方法了取得6了 --------------------编程问答--------------------
引用 14 楼 viena 的回复:
看来懂计算机原理的人很少啊,难道都不是学计算机的?
还是没看到楼主的高效率三个字?
乘除虽然不如加减快,更比为运算慢得多,但还是基本的运算
而一个二进制数转为一个十进制字符串恐怕是一系列比较复杂的操作~
数字转指定进制的字符串就是一个循环取余除进制的过程...
参考我以前写的某转任意进制(蛋疼的话可以弄出64进制)字符串的函数XD.... --------------------编程问答-------------------- 话说这帖也能争起来... --------------------编程问答--------------------
引用 44 楼 viena 的回复:
引用 40 楼 cqsfd 的回复:
你的公式只是找到余数而已,除以1百万
n=1346436457
n - n / 1000000 * 1000000 = 436457
(n%10000000)/1000000 取个余再除 我们应该想办法找到比这个更快的呀

不是这个意思,1346436457除以1000000得1346,然后1346就可以用取个位的方法了取得6了

对啊
现在知道的方法,基本都是取余再除,或者先除再取余
楼主问的应该是比这更快的方法,要不这个问题也就完全没意义了
为什么我们还纠结在如何取余呢? --------------------编程问答-------------------- 个位
int a = 1001;
int b = a % 10 --------------------编程问答-------------------- int getOne(int num)
{
   return num%10;
}

int getN(int num,int n)
{
   if(n == 1)
     return getOne(num);
   int div = 1;
   for(int i = 1; i < n;i++)
     div *= 10;
   int ret = num/div;
   return getOne(ret);
} --------------------编程问答-------------------- 在c#里谈基础算术算法效率?就今天的这些个计算机,用个千万亿次循环做测试,你主观也感觉不出差别吧。大家还是谈谈开发效率吧! --------------------编程问答--------------------
引用 27 楼 wuyazhe 的回复:
引用 26 楼 gsdn00a 的回复:
根据阿非宣传的“知不知”理论,证明.net新旧斑竹是“不懂装懂”的回贴人。


IL是我的软肋,我没说我理解这其中曲直,只是把你贴的例子测试,并没有你贴的结果那么明显,并且我尝试用常量来替换后,得到结果是和你的不同,对IL这层我的确不懂,我只是用我测试的结果来说,你可以说任何一个人不懂装懂,这个都成立,所有人都有不懂的地方。这句话只说明了你讨论问题……


这个二难推理命题只能当作一句玩笑,试图论证它就上当了。VMM是高手,姜还是老的辣。 :)



--------------------编程问答--------------------
引用 38 楼 viena 的回复:
引用 36 楼 langyue555 的回复:
直接去余应该比较快吧

你可以拿我的控制台测试代码去运行下看看


把VMM的代码改造了下,Stopwatch方法不变,保留值变化,去除其它干扰因素,只比较 / 和 %。

Stopwatch watch1 = new Stopwatch();   //    /
Stopwatch watch2 = new Stopwatch();   //    %
private void button2_Click(object sender, EventArgs e)
{
    int m, n;

    watch1.Start();
    for (int i = 100000; i < 100000000; i++)
    {
        m = i - i / 10 * 10;
    }
    watch1.Stop();

    watch2.Start();
    for (int i = 100000; i < 100000000; i++)
    {
        m = i % 10;
    }
    watch2.Stop();

    MessageBox.Show("\\:" + watch1.Elapsed.TotalMilliseconds.ToString()
                   + "\n%:" + watch2.Elapsed.TotalMilliseconds.ToString());
}

三组测试结果数据:
方法1:2223.1071 ,  2231.2673 , 2233.5547
方法2:2189.9218 ,  2186.6355 , 2183.8554

DateTime.Now  和 Stopwatch 两种方法结果一致。
--------------------编程问答-------------------- 取高位的同时避免四舍五入的问题,我解决这个问题的方法是
int Sour = 1234567;
int xMod = x % 100;
Sour -= xMod;
int intCount = Sour / 100 --------------------编程问答--------------------
引用 2 楼 wuyazhe 的回复:
如果一次只取一个,那直接乘除运算好了。
如果一次要取每个位,就转字符串再处理了。

支持 --------------------编程问答-------------------- 52楼,我特地建了个winFrom项目
原样复制你的代码,VS2008,release直接运行
三组测试结果数据如下:

方法1:304.0034  298.0052  301.0316
方法2:385.1388  373.9797  370.9143

看来这种测试确实没啥意义
我的结果总是与你们相反
难道与硬件或者操作系统有关?
我只是疑惑你的为什么那么慢
报下你的测试环境吧

我的:
CPU E5300 (双核2.6G)
内存 4G(2个DDR2 800 2G双通道)
系统 windows server 2008 r2(64位OS) --------------------编程问答--------------------
引用 55 楼 viena 的回复:
看来这种测试确实没啥意义
我的结果总是与你们相反
难道与硬件或者操作系统有关?
我只是疑惑你的为什么那么慢
报下你的测试环境吧

我的:
CPU E5300 (双核2.6G)
内存 4G(2个DDR2 800 2G双通道)
系统 windows server 2008 r2(64位OS)


呵呵,瞧你们很有兴致,我也回了个。确实没啥意义。

我用的测试环境:
CPU 双核1.6G 内存1G  winxp sp3 --------------------编程问答--------------------
引用 50 楼 zicerock 的回复:
在c#里谈基础算术算法效率?就今天的这些个计算机,用个千万亿次循环做测试,你主观也感觉不出差别吧。大家还是谈谈开发效率吧!


呵呵,如果做服务端大量并发、海量数据处理就不这样说了。我使用lucene搜索1000万条记录并排序,就多了一个id比较,整体性能就差了1倍,又500ms变成了1.1s
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,