int (C #)의 첫 번째 숫자를 어떻게 얻을 수 있습니까?


82

C #에서 int의 첫 번째 숫자를 얻는 가장 좋은 방법은 무엇입니까? 내가 생각 해낸 방법은 int를 문자열로 바꾸고 문자열의 첫 번째 문자를 찾은 다음 다시 int로 바꾸는 것입니다.

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

이것이 작업을 수행하는 동안 아마도 그러한 문제에 대한 훌륭하고 간단한 수학 기반 솔루션이있는 것처럼 느껴집니다. 문자열 조작이 어색해집니다.

편집 : 속도 차이에 관계없이 Substring () 대신 mystring [0]은 여전히 ​​문자열 조작입니다.


재귀 적 방법보다 훨씬 느립니다. =)
J. Steen

내 나쁜, 난, 그것은 다른 사람보다 정말 느리게) = 스톱워치를 재설정하는 것을 잊었다
콴 마이

2
음수에서는 실패합니다.
주각

2
int의 첫 번째 숫자는 항상 0 억제와 함께 1입니다. (01010101010100101011011011100101) LOL
Zachary Scott

답변:


126

방법은 다음과 같습니다.

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

그리고 i당신이 필요로 포함됩니다


222

벤치 마크

첫째, 알고리즘의 효율성, 가독성 / 유지 보수 가능성 및 향후 버그가 발생할 가능성을 고려하여 "최상의"솔루션이 의미하는 바를 결정해야합니다. 그러나 신중한 단위 테스트는 일반적으로 이러한 문제를 피할 수 있습니다.

이 예제를 각각 천만 번 실행했으며 결과 값은 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


18
이것은 사소한 soooooo입니다. 나는 당신이 한 일에 감사하고 매우 유익하지만 99 %의 응용 프로그램에는 너무 과잉입니다. 초보 프로그래머가 나쁜 인상을받을 까 봐 걱정됩니다. (가독성보다 하드 코어, 조기 최적화) 그래도 여전히 재미 있습니다. :)
Samantha Branham

7
조회 테이블은 어디에 있습니까?
GvS 2009

2
벤치 마크의 경우 +1이지만 이것이 전체 과잉이라고 동의합니다. 성능이 걱정된다면 처음부터 C #을 사용해서는 안됩니다. :)
GrahamS

15
+1-좋은 물건. 이것은 당신이 코딩을 좋아한다는 것을 명백하게하는 일종의 금도금 디럭스 모델 과잉입니다. 당신에게 많은 칭찬. 그리고 아니, 스튜어트, 나는 이것이 순진한 초보자들의 마음을 오염시킬 것이라고 생각하지 않습니다. 바라건대, 그것은 그들이 소프트웨어에 대한 애정을 키우도록 가르 칠 것입니다.
Mark Brittingham 2009

2
@Vikash-a char를로 int캐스팅하면 문자의 코드 포인트로 0평가 되므로 문자를 캐스팅하면 48로 평가됩니다. 48을 빼면 효과적으로 정수로 변환됩니다. 또 다른 예로, 문자 5를로 캐스팅하면 int53 으로 평가되고 그에서 48을 빼면 5가됩니다.
John Rasch

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

"nice"= 느린 경우
Keltex

나는 옵티마이 저가 첫 번째 버전을 테일 콜 최적화가 가능한 것으로 보길 바랍니다.이 경우 더 느리지 않을 것입니다.
rmeador

1
그러나 @Jared, 여기서 마지막 숫자의 뺄셈은 완전히 불필요합니다. 10으로 나눕니다.
Konrad Rudolph

26

내가 생각 해낼 수있는 최선의 방법은 다음과 같습니다.

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

int firstDigit = value / Math.Pow( 10, numberOfDigits );

divisor = Convert.ToInt32 (Math.Pow (10, Math.Floor (Math.Log10 (value))));를 사용하여 정수와 double 사이의 불필요한 변환을 피할 수 있습니다. firstDigit = 값 / 제수;
MartinStettner

불행히도 값이 1 (0 반환)이거나 값이 음수이면 작동하지 않습니다. 수정 사항은 int numberOfDigits = 1 + Convert.ToInt32 (Math.Floor (Math.Log10 (Math.Abs ​​(value))));
DanDan 2011

18

Anton의 대답에 대한 변형 :

 // 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 창의성 :)
Samantha Branham

누군가가 발견 한 bcl의 함수를 상기시켜줍니다. 그 방법은 읽기에는 꽤 추했지만 기본적으로 루핑 비교를 수행하고 있었으며 10 명 정도의 그룹으로 비교를 묶었습니다. 현대 CPU가 한 번에 비교합니다.
meandmycode

C #은 컴파일 타임에 이러한 const를 생성 할 수있는 방법이 없기 때문에 환상적으로 추악 할뿐입니다. 평가 시간을 제어하는 ​​Lisp와 같은 언어에서 빠른 방법과 우아한 방법은 동일합니다. :-)
Ken

루프를 풀면 if / else 문을 엉망으로 만드는 것보다 확실히 낫습니다. 우아 하고 성능이 뛰어납니다.
Randolpho

3
첫 번째 "if"를 "while"로 만들면 64 비트에서도 작동합니다 (그러나 "더보기"). +1
MartinStettner

5
int myNumber = 8383;
char firstDigit = myNumber.ToString()[0];
// char = '8'

내가 게시 한 것과 동일하지 않습니까? Substring 대신 []를 사용합니다.
Dinah

아니오 : 그것은 문자가 아닌 문자열을 반환 [] 조회 빨리해야
조엘 Coehoorn

사실이지만 여전히 동일한 기본 방법입니다. 문자열 표현을 구문 분석합니다. @Dinah가 뭔가를 찾고 있다고 생각합니다 ... 알다시피 .... 다른.
Randolpho

@Randolpho : 정확합니다. 확실하지 않다면 죄송합니다. 명확히하기 위해 질문을 업데이트했습니다.
Dinah

또한 int를 얻기 위해 firstDigit-'0 '을 반환합니다. (그것은 C에서 작동합니다 ... 나는 그것이 C #에서 작동한다고 생각합니다)
Nicolas Irisarri

5

Lennaert와 같은 아이디어를 가졌습니다.

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 MartinStettner도 같은 생각을했습니다.


@Rasch : 아, 휴거! 숨겨야하고, 특별한 경우에만 꺼내고, 조용히 읽어야합니다 ... 누가 프로그래밍에 영혼이 없다고 말합니까?
Mike Dunlavey

어떻 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))));

시간이 걸리면 전혀 느리지 않아야합니다. 이것은 내 제안이 될 것이고, 루프가없는 순전히 수학적 솔루션이라는 점을 감안할 때 여기에있는 많은 솔루션보다 빠를 수 있습니다. 오늘날 판매되는 모든 x86 프로세서에는 매우 빠르며 뛰어난 부동 소수점 프로세서가 있습니다.
Adam Davis

여기에 Math.Log10을 사용해야한다고 생각합니다
MartinStettner

고마워요, Martin-저는 .NET 수학 라이브러리를 많이 사용하지 않고 Log와 Ln 대신 Log와 Log10이라는 것을 잊었습니다.
mqp

글쎄요, Adam, 최소한 10 ^ (N-1) (n은 자릿수) 더하기 로그가 필요합니다. 반복되는 답변 (N-1 번 나누는 곳)과 비교할 때 적어도 조금 느려 야한다고 생각합니다. 그러나 나는 벤치 마크에 정기적으로 놀란다.
mqp

1
게다가 OP는 성능에 관계없이 더 의미있는 표현을 요구했고 이것이 추구하는 것을 표현하는 가장 직접적인 (수학적) 방법이다.
harpo

3
int temp = i;
while (temp >= 10)
{
    temp /= 10;
}

의 결과 temp


@ck : 어떤 반올림이 발행 되었습니까? 나눗셈은이 경우 정수 나눗셈입니다. 각 나눗셈은 마지막 숫자를 정확히 잘라냅니다 ...
MartinStettner

3

나는 그것이 C #이 아니라는 것을 알고 있지만, 파이썬에서 "숫자의 문자열 표현의 첫 번째 문자를 얻음"이 더 빠르다는 것이 놀랍습니다!

편집 : 아니요, 실수를 저질렀습니다. 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
$

그러나 그것은 다시 정수로 변환합니까?
Samuel

woops, 이제 이치에
맞습니다.

글쎄 그는 이것을 약간 덜 주제에 맞지 않게 만드는 것이 IronPython이라고 말할 수있었습니다
Ravi

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 )a를 트리거하고 다음 System.OverflowException- -2147483648계산합니다.-2147483648 .

구현은 지금까지 가장 빠른 두 구현의 장점을 결합한 것으로 볼 수 있습니다. 이진 검색을 사용하고 불필요한 분할을 방지합니다. 100,000,000 번의 반복이있는 루프 인덱스를 사용한 빠른 벤치 마크는 현재 가장 빠른 구현보다 두 배 빠르다는 것을 보여줍니다.

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

현재 하드웨어에서 가능한 모든 정수 값을 반복하는 데 몇 초도 걸리지 않기 때문에 이와 같은 간단한 함수는 정확성을 쉽게 입증 할 수 있습니다. 이것은 나중에 버그를 수정할 필요가 없기 때문에 예외적으로 읽기 쉬운 방식으로 구현하는 것이 덜 중요하다는 것을 의미합니다.


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)

1
그리고 10k, 100k, 1mil, 10mil, 100mil 등이 있습니까?
Pawel Krakowiak

이런 식으로 할 것입니다. 재귀 함수보다 훨씬 효율적입니다.
Keltex

이 답변은 최고입니다.
Brian

정말 정말 추하고 반복적이며 유지 관리 할 수없는 코드를 희생시키면서 효율성을 구입했습니다. 실수로 순위를 건너 뛴 경우 어떻게됩니까? 이런.
Randolpho

가장 가능성이 높은 항목이 최상위에 있도록 이러한 조건을 다시 정렬해야합니다.
Jason Punyon

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 듀얼 코어 4200+ (2.2GHz)에서 다음 결과를 얻었습니다.

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 Eight Core (4.00GHz)에서 얻을 수 있습니다.

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이 더 빠른지 여부는 CPU에 따라 다르지만 CPU 명령 프로세서의 분기 예측이 새 프로세서에서 더 똑똑하기 때문이라고 추측 할 수 있지만 확실하지는 않습니다.

인텔 CPU가 없습니다. 누군가가 우리를 위해 테스트 할 수 있습니까?


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

답변에 대한 설명을 추가 할 수 있습니까? 이 질문에는 이미 24 개의 다른 답변이 있습니다. 다른 질문보다 귀하의 질문을 사용해야하는 이유를 아는 것이 좋습니다.
Wai Ha Lee

원래 솔루션으로 많은 수를 사용하여 버그가 발생했습니다. 내 솔루션은 더 깨끗합니다. 천만에요.
teodoric8.

솔루션이 -1.
Wai Ha Lee

:) 다음을 사용하십시오 : if (myVal.ToString () [0]! = '-') {....} and-sign is not a number!
teodoric8.

문자열을 확인하는 대신 숫자가 음수가 아닌지 확인하지 않는 이유는 무엇입니까?
Wai Ha Lee

0
while (i > 10)
{
   i = (Int32)Math.Floor((Decimal)i / 10);
}
// i is now the first int

Decimal로 변환하는 이유는 무엇입니까? 또한 바닥이 필요하지 않습니다.
MartinStettner

실제로 필요하지 않은 잠재적 인 반올림 문제가있었습니다.
cjk

(I> = 10) 또는이 10의 배수 실패합니다 동안이어야한다
도마뱀 빌

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으로 반복적으로 나눈 다음 0에 도달하면 하나의 값을 롤백 할 수 있습니다. 문자열 작업은 일반적으로 느리기 때문에 문자열 조작보다 빠를 수 있지만 결코 우아하지는 않습니다.

이 같은:

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

while-condition (curr> 10)을 만들고 prevValue가 필요하지 않습니다.
MartinStettner

> =가 필요합니다. 10의 첫 번째 숫자는 10이 아니라 1이어야합니다
Dinah

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

지금 작동합니다. 또한 abs에 대한 트랩과 함께 재귀 함수를 추가했습니다.
sdellysse

0
int start = curr;
while (start >= 10)
  start /= 10;

이것은 내부적으로 유사한 루프를 구현해야하고 도중에 문자열 객체를 구성 (및 구문 분석)해야하는 ToString () 접근 방식보다 효율적입니다.


0

마지막 숫자를 얻는 매우 쉬운 방법 :

int myInt = 1821;

int lastDigit = myInt - ((myInt/10)*10); // 1821 - 1820 = 1

3
좋지만 문제는 마지막이 아닌 첫 번째 숫자를 얻는 것입니다.
Dinah

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());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.