How can you get the first digit in an int (C#)?

后端 未结 25 2703
遇见更好的自我
遇见更好的自我 2020-12-02 05:43

In C#, what\'s the best way to get the 1st digit in an int? The method I came up with is to turn the int into a string, find the 1st char of the string, then turn it back to

相关标签:
25条回答
  • 2020-12-02 05:52

    Here's how

    int i = Math.Abs(386792);
    while(i >= 10)
        i /= 10;
    

    and i will contain what you need

    0 讨论(0)
  • 2020-12-02 05:53

    Try this

    public int GetFirstDigit(int number) {
      if ( number < 10 ) {
        return number;
      }
      return GetFirstDigit ( (number - (number % 10)) / 10);
    }
    

    EDIT

    Several people have requested the loop version

    public static int GetFirstDigitLoop(int number)
    {
        while (number >= 10)
        {
            number = (number - (number % 10)) / 10;
        }
        return number;
    }
    
    0 讨论(0)
  • 2020-12-02 05:54

    Using all the examples below to get this code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    
    namespace Benfords
    {
        class Program
        {
            static int FirstDigit1(int value)
            {
                return Convert.ToInt32(value.ToString().Substring(0, 1));
            }
    
            static int FirstDigit2(int value)
            {
                while (value >= 10) value /= 10;
                return value;
            }
    
    
            static int FirstDigit3(int value)
            {
                return (int)(value.ToString()[0]) - 48;
            }
    
            static int FirstDigit4(int value)
            {
                return (int)(value / Math.Pow(10, (int)Math.Floor(Math.Log10(value))));
            }
    
            static int FirstDigit5(int value)
            {
                if (value < 10) return value;
                if (value < 100) return value / 10;
                if (value < 1000) return value / 100;
                if (value < 10000) return value / 1000;
                if (value < 100000) return value / 10000;
                if (value < 1000000) return value / 100000;
                if (value < 10000000) return value / 1000000;
                if (value < 100000000) return value / 10000000;
                if (value < 1000000000) return value / 100000000;
                return value / 1000000000;
            }
    
            static int FirstDigit6(int value)
            {
                if (value >= 100000000) value /= 100000000;
                if (value >= 10000) value /= 10000;
                if (value >= 100) value /= 100;
                if (value >= 10) value /= 10;
                return value;
            }
    
            const int mcTests = 1000000;
    
            static void Main(string[] args)
            {
                Stopwatch lswWatch = new Stopwatch();
                Random lrRandom = new Random();
    
                int liCounter;
    
                lswWatch.Start();
                for (liCounter = 0; liCounter < mcTests; liCounter++)
                    FirstDigit1(lrRandom.Next());
                lswWatch.Stop();
                Console.WriteLine("Test {0} = {1} ticks", 1, lswWatch.ElapsedTicks);
    
                lswWatch.Reset();
                lswWatch.Start();
                for (liCounter = 0; liCounter < mcTests; liCounter++)
                    FirstDigit2(lrRandom.Next());
                lswWatch.Stop();
                Console.WriteLine("Test {0} = {1} ticks", 2, lswWatch.ElapsedTicks);
    
                lswWatch.Reset();
                lswWatch.Start();
                for (liCounter = 0; liCounter < mcTests; liCounter++)
                    FirstDigit3(lrRandom.Next());
                lswWatch.Stop();
                Console.WriteLine("Test {0} = {1} ticks", 3, lswWatch.ElapsedTicks);
    
                lswWatch.Reset();
                lswWatch.Start();
                for (liCounter = 0; liCounter < mcTests; liCounter++)
                    FirstDigit4(lrRandom.Next());
                lswWatch.Stop();
                Console.WriteLine("Test {0} = {1} ticks", 4, lswWatch.ElapsedTicks);
    
                lswWatch.Reset();
                lswWatch.Start();
                for (liCounter = 0; liCounter < mcTests; liCounter++)
                    FirstDigit5(lrRandom.Next());
                lswWatch.Stop();
                Console.WriteLine("Test {0} = {1} ticks", 5, lswWatch.ElapsedTicks);
    
                lswWatch.Reset();
                lswWatch.Start();
                for (liCounter = 0; liCounter < mcTests; liCounter++)
                    FirstDigit6(lrRandom.Next());
                lswWatch.Stop();
                Console.WriteLine("Test {0} = {1} ticks", 6, lswWatch.ElapsedTicks);
    
                Console.ReadLine();
            }
        }
    }
    

    I get these results on an AMD Ahtlon 64 X2 Dual Core 4200+ (2.2 GHz):

    Test 1 = 2352048 ticks
    Test 2 = 614550 ticks
    Test 3 = 1354784 ticks
    Test 4 = 844519 ticks
    Test 5 = 150021 ticks
    Test 6 = 192303 ticks
    

    But get these on a AMD FX 8350 Eight Core (4.00 GHz)

    Test 1 = 3917354 ticks
    Test 2 = 811727 ticks
    Test 3 = 2187388 ticks
    Test 4 = 1790292 ticks
    Test 5 = 241150 ticks
    Test 6 = 227738 ticks
    

    So whether or not method 5 or 6 is faster depends on the CPU, I can only surmise this is because the branch prediction in the command processor of the CPU is smarter on the new processor, but I'm not really sure.

    I dont have any Intel CPUs, maybe someone could test it for us?

    0 讨论(0)
  • 2020-12-02 05:54

    Non iterative formula:

    public static int GetHighestDigit(int num)
    {
        if (num <= 0)
           return 0; 
    
        return (int)((double)num / Math.Pow(10f, Math.Floor(Math.Log10(num))));
    }
    
    0 讨论(0)
  • 2020-12-02 05:54

    Here is a simpler way that does not involve looping

    int number = 1234
    int firstDigit = Math.Floor(number/(Math.Pow(10, number.ToString().length - 1))
    

    That would give us 1234/Math.Pow(10, 4 - 1) = 1234/1000 = 1

    0 讨论(0)
  • 2020-12-02 05:55

    The best I can come up with is:

    int numberOfDigits = Convert.ToInt32(Math.Floor( Math.Log10( value ) ) );
    
    int firstDigit = value / Math.Pow( 10, numberOfDigits );
    
    0 讨论(0)
提交回复
热议问题