2017-12-22 17 views
0

아래 주어진 코드는 (int 데이터 형식)으로 최대 10 자리까지 작동하지만 10 자리를 초과하는 숫자의 경우 실패했습니다. 따라서 unsigned long long int을 시도했습니다. 하지만 지금 내 출력은 15로 고정되어, idk 왜? 나를 C로 아주 새로운 것으로 생각해 보라. 평범한 파이썬 배경을 가지고있다.10 자리 이상의 정수에서 연산 할 때 C 결과가 왜곡되는 이유는 무엇입니까?

내가 GCC를 사용하고 (~ 16.04.1 우분투 5.4.0-6ubuntu1) 당신은 잘못된 형식 지정자를 사용했습니다 5.4.0 20160609

#include <stdio.h> //Get number of digits in a int 
unsigned long long int get_len(); 

void main() { 
    unsigned long long int num; 
    printf("Enter the number:"); 
    scanf("%d",&num); 
    printf("\nThe length of number is is: %d \n",get_len(num)); 
} 

unsigned long long int get_len(unsigned long long int z) { 
    unsigned long long int i = 1; 
    while (1) { 
     if ((z/10) > 1) { 
      //printf("Still greater than 1"); 
      i++; 
         z = z/10; 
      continue;} 
     else { 
      return(i+1); 
         break;}}} 
+0

당신은 [GMPlib]와 같은 일부 [의 bignum] (https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic) 라이브러리를 (할 수 있습니다 http://gmplib.org/) –

+0

시간을 절약하고 모든 컴파일러 경고를 활성화합니다. – chux

+1

파이썬은 필요한 경우 자동으로 bignums로 전환하지만 C는 "금속에 더 가깝습니다"그리고 필요한 경우 특정 유형의 번호를 더 큰 번호로 승격 할 수 없습니다. 따라서 현대 컴파일러에서 64 비트 인'unsigned long long int '로 작업하도록 코드를 수정하더라도 소수점 이하 20자를 넘을 수는 없습니다. – usr2564301

답변

8

. scanf("%llu",&num);

scanf에서 잘못된 형식 지정자를 사용하는 것은 정의되지 않은 동작입니다.

언급 된 것과는 별도로, 길이 찾기 로직은 한자리 숫자와 다중 숫자 숫자에서 실패한다는 점에서 잘못되었습니다.

1의 경우 숫자 2을 반환하며 다른 숫자도 마찬가지입니다. (예 : 12) 3을 반환합니다.

큰 숫자의 경우 라이브러리를 선택하거나 (큰 번호 처리) 필요한 옵션 중 하나를 쓸 수 있습니다.

if(scanf("%llu",&num) != 1) { /* error */}과 같은 숫자를 검색합니다. scanf의 반환 값을보다 명확하게 확인하십시오.

+0

하느님, 단 한 자리 숫자를 시도한 적이 없지만 그래도 실패 했어, 내가 바로 잡을거야! 그 점을 지적 해 주셔서 감사합니다! –

2

다음은 또 다른 구현입니다. 다음과 같은 몇 가지 문제가 수정되었습니다.

  1. 메인 반환 유형은 int이어야합니다.
  2. unsigned intget_len() 반환 유형으로 충분합니다.
  3. unsigned intunsigned은 동일합니다. 또한 unsigned long long intint을 제거 할 수 있습니다.
#include <stdio.h> 
unsigned get_len(); 

int main() 
{ 
    unsigned long long num; 

    printf("Enter the number: "); 
    scanf("%llu", &num); 

    printf("\nThe length of number is: %u\n", get_len(num)); 
} 

unsigned get_len(unsigned long long z) 
{ 
    return (z/10 > 0) ? get_len(z/10) + 1 : 1; 
}