Как получить первую цифру в int (C #)?

82

В C #, как лучше всего получить 1-ю цифру в int? Метод, который я придумал, состоит в том, чтобы превратить int в строку, найти 1-й символ строки, а затем вернуть его в int.

int start = Convert.ToInt32(curr.ToString().Substring(0, 1));

Хотя это работает, похоже, что существует хорошее простое математическое решение такой проблемы. Манипуляции со строками кажутся неуклюжими.

Изменить: независимо от разницы в скорости mystring [0] вместо Substring () по-прежнему является просто манипуляцией со строкой

Дина
источник
Это даже медленнее, чем рекурсивный метод. =)
J. Steen
мой плохой, я забыл сбросить секундомер =) он действительно медленнее, чем другие
Quan Mai
2
Это не поможет с отрицательными числами.
плинтус
2
первая цифра int всегда 1 с подавлением нуля (01010101010100101011011011100101) LOL
Zachary Scott

Ответы:

126

Вот как

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

и iбудет содержать то, что вам нужно

Антон Гоголев
источник
222

Контрольные точки

Во-первых, вы должны решить, что вы подразумеваете под «лучшим» решением, разумеется, с учетом эффективности алгоритма, его удобочитаемости / ремонтопригодности и вероятности появления ошибок в будущем. Однако тщательные модульные тесты обычно позволяют избежать этих проблем.

Я запускал каждый из этих примеров 10 миллионов раз, и значение результата - это количество ElapsedTicksпройденных примеров .

Без лишних слов, от самого медленного к самому быстрому, алгоритмы следующие:

Преобразуя в строку, возьмите первый символ

int firstDigit = (int)(Value.ToString()[0]) - 48;

Полученные результаты:

12,552,893 ticks

Использование логарифма

int firstDigit = (int)(Value / Math.Pow(10, (int)Math.Floor(Math.Log10(Value))));

Полученные результаты:

9,165,089 ticks

Зацикливание

while (number >= 10)
    number /= 10;

Полученные результаты:

6,001,570 ticks

Условные

int firstdigit;
if (Value < 10)
     firstdigit = Value;
else if (Value < 100)
     firstdigit = Value / 10;
else if (Value < 1000)
     firstdigit = Value / 100;
else if (Value < 10000)
     firstdigit = Value / 1000;
else if (Value < 100000)
     firstdigit = Value / 10000;
else if (Value < 1000000)
     firstdigit = Value / 100000;
else if (Value < 10000000)
     firstdigit = Value / 1000000;
else if (Value < 100000000)
     firstdigit = Value / 10000000;
else if (Value < 1000000000)
     firstdigit = Value / 100000000;
else
     firstdigit = Value / 1000000000;

Полученные результаты:

1,421,659 ticks

Развернутый и оптимизированный цикл

if (i >= 100000000) i /= 100000000;
if (i >= 10000) i /= 10000;
if (i >= 100) i /= 100;
if (i >= 10) i /= 10;

Полученные результаты:

1,399,788 ticks

Заметка:

каждый тест вызывает, Random.Next()чтобы получить следующийint

Джон Раш
источник
На каком наборе целых чисел прогнали их?
mqp
18
Это оооочень банально. Я ценю то, что вы сделали, и это довольно информативно, но для 99% приложений это слишком сложно. Боюсь, что некоторые начинающие программисты могут произвести плохое впечатление. (жесткая, преждевременная оптимизация вместо удобочитаемости) Тем не менее, это все еще весело. :)
Саманта Бранхам
2
+1 за тесты, но я согласен, что это полный перебор. Если вы ТАК беспокоитесь о производительности, то вам, вероятно, вообще не следует использовать C # :)
GrahamS
15
+1 - Отличный материал. Это своего рода позолоченная роскошная модель, которая просто делает очевидным, что вы любите кодировать. Большое вам спасибо. И нет, Стюарт, я не думаю, что это осквернит умы ничего не подозревающих новичков. Надеюсь, это научит их полюбить программное обеспечение.
Марк Бриттингем,
2
@Vikash - приведение a charк intоценивается к кодовой точке символа, поэтому приведение символа 0оценивается к 48. Вычитание 48 эффективно выполняет преобразование в целое число. Другой пример: приведение персонажа 5к int
Джон Раш,
31

Попробуй это

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

РЕДАКТИРОВАТЬ

Несколько человек запросили версию цикла

public static int GetFirstDigitLoop(int number)
{
    while (number >= 10)
    {
        number = (number - (number % 10)) / 10;
    }
    return number;
}
ДжаредПар
источник
1
Рекурсия для чего-то вроде этого ... Позор вам. Вставьте туда петлю.
Welbog
@Welbog :), Обычно я бы стал. Но по этому вопросу у меня много ностальгии. Это практически первые вопросы, которые мне задают при выполнении задания по CS. В то время я написал по существу это решение.
JaredPar,
Это тот случай, когда "хороший" = медленный
Keltex
Я надеюсь, что оптимизатор увидит в первой версии что-то, что можно оптимизировать с помощью хвостового вызова, и в этом случае он не будет медленнее.
rmeador
1
Но, @Jared, вычитание последней цифры здесь совершенно не нужно. Просто разделите на 10.
Конрад Рудольф
26

Лучшее, что я могу придумать, это:

int numberOfDigits = Convert.ToInt32(Math.Floor( Math.Log10( value ) ) );

int firstDigit = value / Math.Pow( 10, numberOfDigits );
Леннарт
источник
Вы можете избежать ненужных преобразований между целыми числами и числами типа double, используя divisor = Convert.ToInt32 (Math.Pow (10, Math.Floor (Math.Log10 (value)))); firstDigit = значение / делитель;
MartinStettner
К сожалению, это не работает, если значение равно 1 (возвращает 0) или если значение отрицательное. Исправление: int numberOfDigits = 1 + Convert.ToInt32 (Math.Floor (Math.Log10 (Math.Abs ​​(value))));
DanDan
18

вариант ответа Антона:

 // cut down the number of divisions (assuming i is positive & 32 bits)
if (i >= 100000000) i /= 100000000;
if (i >= 10000) i /= 10000;
if (i >= 100) i /= 100;
if (i >= 10) i /= 10;
Майк Данлэйви
источник
Думаю, я бы просто оставил это на /10и /1000. Вы по-прежнему получаете преимущество более агрессивного разделения, но с меньшим беспорядком. +1 за творчество :)
Саманта Бранхам
Напоминает мне функцию в bcl, которую кто-то обнаружил, метод был довольно уродливым для чтения, но в основном он выполнял циклические сравнения и групповые сравнения в группах по десять или около того, зная, что современный процессор сможет лучше обрабатывать группу сравнивает за раз.
meandmycode
Это просто фантастически уродливо, потому что в C # нет способа сгенерировать эти константы во время компиляции (а выполнение этого во время выполнения будет дороже, чем то, что вы пытаетесь предотвратить). В таком языке, как Lisp, где вы управляете временем оценки, быстрый и элегантный способы одинаковы. :-)
Кен
Развертывание цикла, безусловно, лучше, чем масса операторов if / else. Это одновременно элегантно и функционально .
Randolpho
3
если вы сделаете первое «если» a «while», оно также будет работать с 64-битными (но даже «некрасиво»). +1
MartinStettner
5
int myNumber = 8383;
char firstDigit = myNumber.ToString()[0];
// char = '8'
Джгауффин
источник
Разве это не идентично тому, что я опубликовал? Он просто использует [] вместо Substring
Дина
Нет: он возвращает символ, а не строку, и поиск [] должен быть быстрее
Джоэл Кохорн
Это правда, но это все тот же базовый метод - анализ строкового представления. Думаю, @Dinah что-то ищет ... ну ... другое.
Randolpho
@Randolpho: точно. Извините, если я не совсем понял это. Я обновил вопрос, чтобы уточнить.
Дина,
Я бы также вернул firstDigit-'0 ', чтобы получить int. (он работает в c ... я думаю, это работает в C #)
Николас Ирисарри,
5

Была такая же идея, как у Леннарта

int start = number == 0 ? 0 : number / (int) Math.Pow(10,Math.Floor(Math.Log10(Math.Abs(number))));

Это также работает с отрицательными числами.

аквинский
источник
4

Если вы думаете, что ответ Keltex уродлив, попробуйте этот, он ДЕЙСТВИТЕЛЬНО уродливый и даже быстрее. Он выполняет развернутый двоичный поиск для определения длины.

 ... leading code along the same lines
/* i<10000 */
if (i >= 100){
  if (i >= 1000){
    return i/1000;
  }
  else /* i<1000 */{
    return i/100;
  }
}
else /* i<100*/ {
  if (i >= 10){
    return i/10;
  }
  else /* i<10 */{
    return i;
  }
}

PS У Мартина Штеттнера была такая же идея.

Майк Данлэйви
источник
@Rasch: Ах, восторг! Его следует прятать, приносить только для особых случаев и читать приглушенным тоном ... Кто сказал, что у программирования нет души?
Майк Данлэйви,
как насчетi=(...moreugly...)i>=100?i>=1000?i/1000:i/100:i>=10?i/10:i;
Дэвид Мердок
3

Очевидный, но медленный математический подход:

int firstDigit = (int)(i / Math.Pow(10, (int)Math.Log10(i))));
mqp
источник
Время, оно не должно быть медленным. Это должно было быть моим предложением, и, учитывая, что это чисто математическое решение без цикла, оно, возможно, быстрее, чем многие решения здесь. Имейте в виду, что каждый проданный сегодня процессор x86 имеет очень, очень быстрый и способный процессор с плавающей запятой.
Адам Дэвис,
Я думаю, вам действительно стоит использовать здесь Math.Log10,
Мартин
Спасибо, Мартин, я не особо использую математические библиотеки .NET и забыл, что это Log и Log10 вместо Log и Ln.
mqp
Что ж, Адам, по крайней мере нужно взять 10 ^ (N-1) (n - количество цифр) плюс нужно взять логарифм. По сравнению с циклическим ответом (где вы делите N - 1 раз) мне кажется, что он должен быть хотя бы немного медленнее. Но я регулярно удивляюсь тестам, так что кто знает.
mqp
1
Кроме того, OP запросил более осмысленное выражение, без учета производительности, и это наиболее прямой (математический) способ выразить то, что требуется.
harpo
3
int temp = i;
while (temp >= 10)
{
    temp /= 10;
}

Результат в temp

Дуглас Лидер
источник
@ck: Какое округление выдано? В данном случае деление - это целочисленное деление, каждое деление точно отсекает последнюю цифру ...
Мартин Стеттнер,
3

Я знаю, что это не C #, но удивительно любопытно, что в python «получить первый символ строкового представления числа» быстрее!

РЕДАКТИРОВАТЬ : нет, я совершил ошибку, я забыл снова построить int, извините. В развернутой версии она самая быстрая.

$ cat first_digit.py
def loop(n):
    while n >= 10:
        n /= 10
    return n

def unrolled(n):
    while n >= 100000000: # yea... unlimited size int supported :)
        n /= 100000000
    if n >= 10000:
        n /= 10000
    if n >= 100:
        n /= 100
    if n >= 10:
        n /= 10
    return n

def string(n):
    return int(str(n)[0])
$ python -mtimeit -s 'from first_digit import loop as test' \
    'for n in xrange(0, 100000000, 1000): test(n)'
10 loops, best of 3: 275 msec per loop
$ python -mtimeit -s 'from first_digit import unrolled as test' \
    'for n in xrange(0, 100000000, 1000): test(n)'
10 loops, best of 3: 149 msec per loop
$ python -mtimeit -s 'from first_digit import string as test' \
    'for n in xrange(0, 100000000, 1000): test(n)'
10 loops, best of 3: 284 msec per loop
$
ZeD
источник
Но преобразует ли он его обратно в целое число?
Samuel
упс, теперь это имеет смысл -.-
ZeD
хорошо, он мог бы сказать, что это был IronPython, чтобы сделать это немного менее неуместным
Рави
3

Я только что наткнулся на этот старый вопрос и почувствовал себя склонным предложить другое предложение, поскольку ни один из других ответов пока не возвращает правильный результат для всех возможных входных значений, и его все еще можно сделать быстрее:

public static int GetFirstDigit( int i )
{
    if( i < 0 && ( i = -i ) < 0 ) return 2;
    return ( i < 100 ) ? ( i < 1 ) ? 0 : ( i < 10 )
            ? i : i / 10 : ( i < 1000000 ) ? ( i < 10000 )
            ? ( i < 1000 ) ? i / 100 : i / 1000 : ( i < 100000 )
            ? i / 10000 : i / 100000 : ( i < 100000000 )
            ? ( i < 10000000 ) ? i / 1000000 : i / 10000000
            : ( i < 1000000000 ) ? i / 100000000 : i / 1000000000;
}

Это работает для всех целочисленных значений со знаком, включая -2147483648наименьшее целое число со знаком и не имеющее положительного эквивалента. Math.Abs( -2147483648 )запускает System.OverflowExceptionи - -2147483648вычисляет -2147483648.

Реализацию можно рассматривать как комбинацию преимуществ двух самых быстрых на данный момент реализаций. Он использует двоичный поиск и избегает лишних делений. Быстрый тест с индексом цикла с 100000000 итераций показывает, что он в два раза быстрее, чем самая быстрая реализация на данный момент.

Он заканчивается после 2 829 581 тика.

Для сравнения я также измерил исправленный вариант самой быстрой на данный момент реализации, который занял 5 664 627 тиков.

public static int GetFirstDigitX( int i )
{
    if( i < 0 && ( i = -i ) < 0 ) return 2;
    if( i >= 100000000 ) i /= 100000000;
    if( i >= 10000 ) i /= 10000;
    if( i >= 100 ) i /= 100;
    if( i >= 10 ) i /= 10;
    return i;
}

Принятый ответ с тем же исправлением потребовал 16 561 929 тиков для этого теста на моем компьютере.

public static int GetFirstDigitY( int i )
{
    if( i < 0 && ( i = -i ) < 0 ) return 2;
    while( i >= 10 )
        i /= 10;
    return i;
}

Правильность таких простых функций легко проверить, так как итерация всех возможных целочисленных значений на текущем оборудовании занимает не более нескольких секунд. Это означает, что менее важно реализовать их в исключительно удобочитаемом виде, поскольку в дальнейшем просто никогда не будет необходимости исправлять ошибку внутри них.

x4u
источник
2

Очень просто (и, вероятно, довольно быстро, потому что включает только сравнения и одно деление):

if(i<10)
   firstdigit = i;
else if (i<100)
   firstdigit = i/10;
else if (i<1000)
   firstdigit = i/100;
else if (i<10000)
   firstdigit = i/1000;
else if (i<100000)
   firstdigit = i/10000;
else (etc... all the way up to 1000000000)
Keltex
источник
1
А еще есть 10 тысяч, 100 тысяч, 1 мил, 10 мил, 100 мил и так далее?
Павел Краковяк,
Я бы так и поступил. Намного эффективнее, чем эта рекурсивная функция.
Keltex
Этот ответ - лучший из всех возможных.
Брайан,
Эффективность куплена за счет действительно действительно ужасного, повторяющегося, неподдерживаемого кода. Что, если вы случайно пропустили ранг? Упс.
Randolpho
Вам действительно следует изменить порядок этих условий так, чтобы наиболее вероятные были наверху ...
Джейсон Пуньон
1

Провел несколько тестов с одним из моих коллег и обнаружил, что большинство решений не работают для чисел меньше 0.

  public int GetFirstDigit(int number)
    {
        number = Math.Abs(number); <- makes sure you really get the digit!

        if (number < 10)
        {
            return number;
        }
        return GetFirstDigit((number - (number % 10)) / 10);
    }
Юнес
источник
1

Используя все приведенные ниже примеры, чтобы получить этот код:

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();
        }
    }
}

Я получаю эти результаты на AMD Ahtlon 64 X2 Dual Core 4200+ (2,2 ГГц):

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

Но получите их на восьмиядерном процессоре AMD FX 8350 (4,00 ГГц).

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

Так что, будет ли метод 5 или 6 быстрее, зависит от ЦП, я могу только предположить, что это связано с тем, что предсказание ветвлений в командном процессоре ЦП более умное на новом процессоре, но я не совсем уверен.

У меня нет процессоров Intel, может, кто-нибудь нам поможет?

Аарон Мургатройд
источник
1

Проверьте это тоже:

int get1digit(Int64 myVal)
{
    string q12 = myVal.ToString()[0].ToString();
    int i = int.Parse(q12);
    return i;
}

Также хорошо, если вам нужно несколько номеров:

int get3digit(Int64 myVal) //Int64 or whatever numerical data you have
{
    char mg1 = myVal.ToString()[0];
    char mg2 = myVal.ToString()[1];
    char mg3 = myVal.ToString()[2];
    char[] chars = { mg1, mg2, mg3 };
    string q12= new string(chars);
    int i = int.Parse(q12);
    return i;
}
teodoric8.
источник
Не могли бы вы добавить пояснения к своему ответу? На этот вопрос уже есть 24 других ответа - было бы хорошо знать, почему нам следует использовать ваш, а не другие.
Вай Ха Ли
В исходном решении у меня было несколько ошибок с использованием больших чисел. Мое решение чище. Пожалуйста.
teodoric8.
Ваше решение не подходит для -1.
Вай Ха Ли
:) используйте это тогда: if (myVal.ToString () [0]! = '-') {....} и - знак не является числом!
teodoric8.
Почему бы вместо проверки строки не проверить, не является ли число отрицательным?
Вай Ха Ли
0
while (i > 10)
{
   i = (Int32)Math.Floor((Decimal)i / 10);
}
// i is now the first int
cjk
источник
Почему вы переходите на десятичный формат? Также пол не нужен.
MartinStettner,
Это было связано с потенциальными проблемами округления, которые на самом деле не нужны.
cjk
Должно быть while (i> = 10), иначе это не удастся, если число кратно 10.
Bill the Lizard
0

Неитерационная формула:

public static int GetHighestDigit(int num)
{
    if (num <= 0)
       return 0; 

    return (int)((double)num / Math.Pow(10f, Math.Floor(Math.Log10(num))));
}
Митч Уит
источник
Реализация журнала является итеративной, поскольку требует алгоритма поиска корня
Джаспер Беккерс
0

Чтобы дать вам альтернативу, вы можете несколько раз разделить целое число на 10, а затем откатить одно значение, когда достигнете нуля. Поскольку строковые операции обычно выполняются медленно, это может быть быстрее, чем манипуляции со строками, но отнюдь не элегантно.

Что-то вроде этого:

while(curr>=10)
     curr /= 10;
Джош Джордан
источник
Сделайте условие while (curr> 10), и вам не нужно prevValue
Мартин
> = необходимо. Первая цифра 10 должна быть 1, а не 10
Дина
0
start = getFirstDigit(start);   
public int getFirstDigit(final int start){
    int number = Math.abs(start);
    while(number > 10){
        number /= 10;
    }
    return number;
}

или же

public int getFirstDigit(final int start){
  return getFirstDigit(Math.abs(start), true);
}
private int getFirstDigit(final int start, final boolean recurse){
  if(start < 10){
    return start;
  }
  return getFirstDigit(start / 10, recurse);
}
Sdellysse
источник
Должно работать сейчас. Также добавлена ​​рекурсивная функция с ловушкой для абс.
sdellysse
0
int start = curr;
while (start >= 10)
  start /= 10;

Это более эффективно, чем подход ToString (), который внутренне должен реализовывать аналогичный цикл и должен конструировать (и анализировать) строковый объект по пути ...

MartinStettner
источник
0

Очень простой способ получить последнюю цифру:

int myInt = 1821;

int lastDigit = myInt - ((myInt/10)*10); // 1821 - 1820 = 1
Даниэль
источник
3
Это хорошо, но вопрос в том, чтобы получить первую цифру, а не последнюю.
Дина
0

Это то, что я обычно делаю, пожалуйста, обратитесь к моей функции ниже:

Эта функция может извлекать первое число из любой строки, которую вы можете изменить, и использовать эту функцию в соответствии с вашим использованием.

   public static int GetFirstNumber(this string strInsput)
    {
        int number = 0;
        string strNumber = "";
        bool bIsContNo = true;
        bool bNoOccued = false;

        try
        {
            var arry = strInsput.ToCharArray(0, strInsput.Length - 1);

            foreach (char item in arry)
            {
                if (char.IsNumber(item))
                {
                    strNumber = strNumber + item.ToString();

                    bIsContNo = true;

                    bNoOccued = true;
                }
                else
                {
                    bIsContNo = false;
                }

                if (bNoOccued && !bIsContNo)
                {
                    break;
                }


            }

            number = Convert.ToInt32(strNumber);

        }
        catch (Exception ex)
        {

            return 0;
        }

        return number;

    }
срееюши
источник
-2

Вот более простой способ, не требующий цикла

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

Это даст нам 1234 / Math.Pow (10, 4-1) = 1234/1000 = 1

Росс Годдард
источник
Невозможно неявно преобразовать тип double в int.
Younes
-2
int i = 4567789;
int digit1 = int.Parse(i.ToString()[0].ToString());
Jrod
источник