할 수없는 언어로 매우 많은 수를 처리합니까?


15

언어 구조가 특정 값보다 큰 수를 처리 할 수없는 경우 매우 큰 수 (무한 수-수레가없는 부동 소수점 수)에서 계산을 수행하는 방법에 대해 생각하고 있습니다.

나는이 질문을하는 첫 번째도 마지막이 아니라고 확신하지만 사용중인 검색어는 이러한 상황을 처리하는 알고리즘을 제공하지 않습니다. 오히려 대부분의 제안은 언어 변경이나 변수 변경을 제공하거나 내 검색과 관련이없는 것에 대해 이야기합니다. 약간의 안내가 필요합니다.

다음과 같은 알고리즘을 스케치합니다.

  1. 언어에 대한 정수 변수의 최대 길이를 결정하십시오.

  2. 숫자가 변수의 최대 길이의 절반보다 길면 배열로 나눕니다. (작은 놀이방을 줘)

  3. 배열 순서 [0] = 가장 오른쪽에있는 숫자 [n-max] = 가장 왼쪽에있는 숫자

    전의. 숫자 : 29392023 배열 [0] : 23, 배열 [1] : 20, 배열 [2] : 39, 배열 [3] : 29

마크 오프 포인트로 변수 길이의 절반을 설정했기 때문에 1, 10, 100 등을 계산할 수 있습니다. 중간 마크를 통해 변수 최대 길이가 0에서 9999999999까지 10 자리 인 경우 다음을 알 수 있습니다. 5 자리로 반으로 줄이면 놀이방이 생깁니다.

따라서 더하거나 곱하면 array [0]의 6 번째 숫자 (오른쪽에서)가 array [1]의 첫 번째 숫자와 같은 곳임을 확인하는 변수 검사기 기능을 사용할 수 있습니다.

나누기 및 빼기에는 아직 생각하지 않은 자체 문제가 있습니다.

프로그램보다 더 많은 수를 지원하는 최상의 구현에 대해 알고 싶습니다.


1
가장 먼저 떠오르는 것은 Java의 BigInteger입니다. docs.oracle.com/javase/6/docs/api/java/math/BigInteger.html
Ivan

여기있는 사람이 누구나 알고 추천 할 수있는 언어입니까, 아니면 모호하고 독점적 인 것입니까?
FrustratedWithFormsDesigner

어떤 언어를 아직 사용하고 싶은지 모르겠습니다. 나는 PHP를 가장 많이 알고 있지만 그 언어로하고 싶지 않습니다. Lisp은 내가 읽은 것으로부터 길이에 대한 제한이 없기 때문에 매력적입니다. 그러나 그것이 어떻게 작동하는지 알고 싶어하는 개인적인 결함은 내가 섬에 갇혀 있으면 qbasic에서 자유 로워지기를 원합니다. (재미 있기도합니다. 저는 항상 많은 수의 계산을 생각하고 일부 온라인 계산기는 작업이 너무 번거 롭습니다.)
Mallow

답변:


25

작업중인 언어에 대한 임의 정밀도 산술 ( "다중 정밀도"또는 "큰 숫자"라고도 함) 라이브러리를 찾고 있습니다. 예를 들어, C로 작업하는 경우 GNU Bignum 라이브러리-> http://gmplib.org/를 사용할 수 있습니다.

그것이 어떻게 작동하는지 이해하려면 자신의 큰 숫자 라이브러리를 작성하여 사용할 수도 있습니다. 이를 처리하는 가장 간단한 방법은 배열을 사용하는 것입니다. 여기서 각 요소는 작업중인 숫자의 숫자입니다. 그런 다음 더하기, 빼기, 곱하기, 나누기, 지수 등을 수행하는 모든 함수를 구현해야합니다.


5
물론 "숫자"는 상대적이며, 많은 bignum 라이브러리는 기본 256 (부호없는 바이트 [])에서 2 ^ 64 (부호없는 long [])의 숫자를 사용합니다.
ratchet freak

1
'digit'는 기본 256 자리의 배열 일 수 있음을 이해했는지 확인하십시오. 나는 내가 잘못 될 것 같아요,베이스 (256)에 수학을하는 것은 기본 88보다 쉽습니다하지만 여전히 꽤 작업 (적어도 내가 종이 하하의 장에 지난 밤을했을 때)
맬 로우

1
"베이스 256에서 수학을하는 것은베이스 88보다 쉽습니다." 그릇된. 그들은 똑같이 쉽습니다.
S.Lott

2
@ S.Lott : um ... 비트 단위 연산을 사용할 수있는 경우 기본 256에서 수학을 수행하는 것이 기본 88보다 확실히 쉽습니다.
Jason S

1
자신의 더하기 / 빼기 / 곱하기는 매우 간단합니다. 조건부 뺄셈과 비트 시프 팅의 연습이되는 바이너리로 구현하지 않으면 나누기가 어렵습니다.
Jason S

13

잘 알려진 문제입니다 : 임의 정밀도 산술

사용중인 언어로이 문제가 해결되지 않으면 먼저 타사 라이브러리를 찾으십시오. 찾을 수 없거나 궁금한 경우 구현하십시오. Wikipedia 기사에는 고전적인 구현에 대한 좋은 참고 자료가 있습니다.


6

많은 수를 다룰 때 가장 기본적인 디자인 결정 중 하나는 어떻게 많은 수를 대표 할 것인가?

문자열, 배열, 목록 또는 사용자 정의 (자체) 스토리지 클래스입니다.

결정이 내려지면 실제 수학 연산은 작은 부분으로 나뉘어 int 또는 정수와 같은 고유 언어 유형으로 실행될 수 있습니다.

나는 매우 기초적인 내용을 포함 시켰습니다C # .Net에는 결과적으로 많은 수를 문자열로 저장하는 ADDITION 예제 . 들어오는 "숫자"도 문자열이므로 매우 큰 숫자로 보낼 수 있습니다. 예제는 정수를 단순하게 유지하기위한 것임을 명심하십시오.

문자열을 사용하더라도 여기에 표시된대로 문자 수 또는 숫자의 "숫자"에 제한이 있습니다.

.NET 문자열의 가능한 최대 길이는 얼마입니까?

그러나 .Net에 대한 int32 또는 int64 기본 유형을 넘어서 실제로 큰 숫자를 추가 할 수 있습니다.

어쨌든, 여기에 문자열 스토리지 구현이 있습니다.

/// <summary>
/// Adds two "integers".  The integers can be of any size string.
/// </summary>
/// <param name="BigInt1">The first integer</param>
/// <param name="BigInt2">The second integer</param>
/// <returns>A string that is the addition of the two integers passed.</returns>
/// <exception cref="Exception">Can throw an exception when parsing the individual parts     of the number.  Callers should handle. </exception>
public string AddBigInts(string BigInt1, string BigInt2)
{
    string result = string.Empty;

    //Make the strings the same length, pre-pad the shorter one with zeros
    int length = (BigInt1.Length > BigInt2.Length ? BigInt1.Length : BigInt2.Length);
    BigInt1 = BigInt1.PadLeft(length, '0');
    BigInt2 = BigInt2.PadLeft(length, '0');

    int remainder = 0;

    //Now add them up going from right to left
    for (int i = (BigInt1.Length - 1); i >= 0; i--)
    {
        //If we don't encounter a number, this will throw an exception as indicated.
        int int1 = int.Parse(BigInt1[i].ToString());
        int int2 = int.Parse(BigInt2[i].ToString());

        //Add
        int add = int1 + int2 + remainder;

        //Check to see if we need a remainder;
        if (add >= 10)
        {
            remainder = 1;
            add = add % 10;
        }
        else
        {
            remainder = 0;
        }

        //Add this to our "number"
        result = add.ToString() + result;
    }

    //Handle when we have a remainder left over at the end
    if (remainder == 1)
    {
        result = remainder + result;
    }

    return result;
}

나는 그것이 당신에게 당신의 구현에 대한 아이디어를 제공하기를 바랍니다. 샘플 코드는 아마도 최적화되지 않았거나 이와 비슷한 것이 아닙니다. 그것은 어떻게 할 수 있는지에 대한 아이디어를 제공하기위한 것입니다.


멋있는!! 고맙게도 여분의 비트를 복잡하게 만들었던 나머지 부분을 정리하는 데 도움이됩니다.
Mallow

-2

이것은 나를 위해 더 빨리 작동합니다.

static string Add(string a, string b)
        {
            string c = null;

            if (Compare(a, b) < 0)
            {
                c = a;
                a = b;
                b = c;
            }

            StringBuilder sb = new StringBuilder();

            b = b.PadLeft(a.Length, '0');

            int r = 0;

            for (int i = a.Length - 1; i >= 0; i--)
            {
                int part = a[i] + b[i] + r - 96;

                if (part <= 9)
                {
                    sb.Insert(0, part);

                    r = 0;
                }
                else
                {
                    sb.Insert(0, part - 10);

                    r = 1;
                }
            }

            if (r == 1)
            {
                sb.Insert(0, "1");
            }

            return sb.ToString();
        }

2
이 사이트는 대한 개념 질문과 답변이 일을 설명 할 것으로 예상된다. 설명 대신 코드 덤프를 던지는 것은 IDE에서 화이트 보드로 코드를 복사하는 것과 같습니다. 친숙하고 때로는 이해할 수 있지만 이상하게 느껴집니다. 화이트 보드에는 컴파일러가 없습니다
gnat

이 사이트는 교환이므로 가능한 한 서로를 돕기 위해 노력합니다. 어쩌면 StackOverflow에서 그러한 의견을 말해야하지만 내 접근 방식을 돕기 위해 노력했습니다. 누군가가 여전히 설명이 필요하다면, 그는 그것을 요구할 것입니다. 나는 여기에서 끝까지 시작하여 숫자로 된 표준 수학적 덧셈을합니다.
Andranik Sargsyan

모기에 동의하십시오. 코드를 덤프하기 전에 알고리즘을 설명하십시오.
Frank Hileman 17

설명이없는 코드를 버리는 것만으로도 복사 할 수 있습니다. 이것이 SoftwareEngineering에서 어떻게 유용한 지 모르겠습니다. 아마도 StackOverflow에 있지만 두 사이트는 실제로 완전히 다른 목적을 가지고 있습니다.
Laiv
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.