유휴 게임은 그렇게 많은 수를 어떻게 처리합니까?


31

Tap titans 및 Cookie Clicker와 같은 게임이 그렇게 많은 수를 처리하는 방법이 궁금합니다.

유휴 게임을 구현하려고하지만 C #에서 지원하는 가장 큰 숫자 형식은 10 진수입니다.

최대 10 ^ 500을 지원하려고합니다. 부동 소수점이어야합니다

어떻게 처리 할 수 ​​있습니까?

PS 그것은 크로스 플랫폼, 즉 PC, Mac, iOS, Android 및 Unity와 호환되어야합니다.


2
내가 정확하게 기억한다면, 당신은 Cookie Clicker의 코드에 접근 할 수 있습니다. 그래서 당신은 그것을 확인할 수 있습니다 ...
Vaillancourt

아니요, 이미 Cookie Clicker를 차단했습니다!
Arturo Torres Sánchez

2
Unity 게임 인 TimeClickers 의 디 컴파일 된 소스를 살펴 보았습니다 . 그들은 단지 사용 double합니다. 그래도 BigInteger를 사용했을 것 입니다.
BlueRaja-대니 Pflughoeft

1
@VioletGiraffe : 동의합니다. OP가 질문을 명확하게하는 데 도움이되도록 구체적으로 의심하고 싶습니다. 질문과 관련하여 "유휴 게임"이란 무엇입니까? 게임의 숫자가 큰 특별한 경우)? " 그러한 숫자"(나 자신이 강조한) 는 어떤 종류의 숫자를 가리 킵니까? 숫자를 얼마나 크게 원하십니까?
또는 매퍼

항상 그러한 큰 수를 문자열에 저장하고 문자열에 대한 합계를 수행하는 함수를 쉽게 구현할 수 있습니다.
dev-masih

답변:


40

12.567T (조)로 12,567,000,000,000을 표시하려는 경우와 같이 완전한 정확도없이 방대한 숫자를 저장하려는 경우 표준 float / decimal 값을 사용하고 적절한 접미사로 첫 x 유효 숫자를 표시하면 됩니다. 이렇게 팔각형에있을 때, 각각의 개별 정수 증분에 관심을 가져야합니까?


4
이것은 아마도 가장 합리적인 대답 일 것입니다. Cookie Clicker는 JavaScript에서 표준 float를 사용한다고 확신합니다. 내가 그것을 "해킹"했을 때 (읽기 : 콘솔과 엉망) 숫자가 1e308에 도달했을 때 점프했습니다. "무한대"에 내가 XD를 원했던 무엇이든 구매할 수 있었다
어두운 Absol Niet

1
큰! 텍스트가 "무한대"로 넘어 간다는 사실은 개발자가이 사건을 수 호적으로 코딩 한 것처럼 느껴집니다. 또한 단순성은 왕입니다.
로스 테일러 터너

19
@RossTurner- "Infinity"라는 텍스트를 표시하는 데 관련된 코딩은 없었을 것입니다. infinity는 float가 가질 수있는 값일 뿐이며 JavaScript는 다른 많은 언어와 마찬가지로 표시 방법을 알고 있습니다.
Jibb Smart

표준 부동 소수점 (이중 정밀도, 8 ​​바이트)은 원래 질문에서 요구하는 것처럼 최대 10 ^ 500의 숫자를 나타낼 수 없으며 ~ 10 ^ 300까지 올라갑니다. 그것이 충분하지 않으면 언어에 따라 사소하지 않을 수있는 사중 정밀도 부동 소수점을 사용해야합니다.
Peteris

1
모든 프로그래머가 부동 소수점 숫자에 대해 알아야 할 사항 : floating-point-gui.de
Steve

20

BigInteger 와 같은 것을 사용할 수 있습니다. 실수하지 않은 경우 .net 4.0에서만 사용할 수 있습니다 (모든 단일 빌드 플랫폼에서 지원하지는 않음).

그러나 .net4.0을 요구하지 않고이 기능을 가져 오려는 일부 라이브러리가 있습니다. 예를 들어 여기 .

또는 승수를 추적하여 작은 숫자를 사용하여 큰 숫자를 나타낼 수 있습니다. 예를 들면 다음과 같습니다.

double value = 9;
enum Multiplier {
   Hundred,
   Thousand,
   Million,
   Billion,
   Trillion
}

이제 9의 값을 갖더라도 곱셈기와 결합하면 9 조를 9 조로 효과적으로 표현할 수 있습니다 ( "조"를 넣거나 값 끝에 0을 추가 할 무언가를 작성하여) ).


BigInteger숫자의 String 또는 Byte [] 표현을 사용하는 것과 같은 클래스 는 실제로 두 개의 "숫자를 Strings 또는 Bytes"로 더하고 빼는 자체 클래스를 만들 수 있다는 점에 주목할 가치가 있습니다 . 필요하지는 않지만 곱셈이나 나눗셈 또는 기타 고급 기능을 지원할 수는 있지만 메모리가 부족할 수있는 물리적 한계는 항상 있음을 명심해야합니다.
DoubleDouble

1
각 바이트에는 숫자의 크기에 256이 곱해집니다. 숫자를 나타내려고하는 메모리가 부족하면 숫자에 실제 값이 없었습니다. 256 ^ (20 억) = 2 ^ 8 ^ (20 억) = 2 ^ (160 억) ~ = 10 ^ (50 억) (wolframalpha는 마지막 변환을 시도했습니다. 150 자리 (<500 비트)와 같은 관측 가능한 유니버스에서 개별 Planck 볼륨을 지정할 수 있습니다.
MichaelS

11

Unity에서 사용하기 위해 자신의 클래스를 작성해야 할 수도 있지만 특히 어렵지는 않습니다.

내부적으로는 정수 목록 (예 :)이 될 수 있으며 목록의 List<int>각 요소는 9 자리 그룹에 해당합니다. 각 정수의 범위는 0-999 999 999입니다. 정수는 20 억을 약간 지원할 수 있으며, 부호가없는 경우 두 배를 두 배 늘릴 1 000 000 000수 있습니다. 큰 숫자를 문자열로 쉽게 변환하여 표시 할 수 있습니다. return group[i].ToString() + group[i-1].ToString() and so on일반 데이터 유형의 범위를 벗어난 그룹의 합계를 표시하는 방법을 알아내는 것보다 이미 10 진수 ( ) 를 연결하는 것이 더 쉽습니다 .

따라서 목록의 첫 번째 int는 1을 나타냅니다. 다음은 수십억입니다. 다음은 수조 개 등입니다.

덧셈과 뺄셈은 펜과 페이퍼 덧셈과 뺄셈과 같은 방식으로 작동합니다. 여기서 오버플로를보고 다음 "숫자"로 넘겨야하지만 0-9 범위의 숫자 대신 숫자의 범위는 다음과 같습니다. 0 ~ 999 999 999입니다.


10

큰 숫자를 처리하기 위해 나는 Tower of Hero 와 같은 좋은 예라고 생각 합니다. 왼쪽 상단 :

1

2
(출처 : mzstatic.com )

게임 플레이에 들어 가지 않고 숫자를 처리하는 방법은 비교적 간단합니다. 두 개의 버킷이 있습니다. 탑에서 높이 올라가 "골드"를 더 많이 만들면 두 버킷은 단순히 더 큰 숫자를 나타냅니다.

120 
120M320K - 120 Million
120B631M - 120 Billion
120T134B - 120 Trillion

게임이 T를 통과하면 a, b, c ... z, aa, ab, ...로 이동합니다.

56aa608z

이 방법으로도, 게임을 계속 진행하지 않으면서도 얼마나 많은 금을 벌 었는지 알 수 있습니다.

당신의 숫자가 Trillions를 지났을 때 수백만을 정말로 걱정합니까?

Int, Big Int, Float, Double, Decimal 등의 숫자를 유지합니까? 맞춤 배열? 이러한 "퍼지"방식으로 숫자를 처리 할 때는 중요하지 않다고 생각합니다.

문제가 될 수있는 모든 것이 가장 중요한 부분입니다 (이 경우 첫 6 개). 그 후, 다음 3 개 또는 6 개는 아마도 몇 백 K를 벌어 들인 이후 수백만에 이월 할 수 있습니다. T를 쳤을 때 수백 K는 당신에게 영향을 미치지 않을 것입니다.

귀하의 마일리지는 다양합니다 (원하는 / 필요에 따라 다름) ... 단지 내가 좋은 / 간단한 예라고 생각하는 것에 2c를 제시하겠다고 생각했습니다.

편집하다:

번호 매기기 시스템을 구현하는 방법에 대한 추가 생각 : XXXX.YYY (...) xZZZ : 3 개의 중요한 부분이있는 숫자가 있습니다.

X is the most significant digits, 
Y trailing 
Z the multiplier (multiple of 3).

따라서 120.365x1은 120k365 ... 120.365x2는 120M365K ... 등입니다. 4 개의 선행 (1200.365x2)을 누른 다음 숫자를 1.200365 (...) x3으로 회전합니다. 밤. 1B200M이 있습니다.

XY는 Decimal 또는 Float에 쉽게 맞습니다 .Z는 옆에 int / unsigned int로 앉아 있습니다.

부동 소수점을 사용하면 점 뒤에 상당한 자릿수를 유지하지만 점점 더 중요하지 않은 숫자를 유지할 수 있습니다.

Z는 쉽게 이해할 수있는 숫자 블록을 쉽게 나타냅니다.

K = 1
M = 2
B = 3
T = 4
a = 5 
...
z = 31 (I may be off on this)
aa = 32
...
az = 58
ba = 59
...
...

1

많은 수를 처리하는 쉬운 방법은 단순히 둘 이상의 INTEGER 값을 가진 다음 오버플로를 수행하는 것입니다. 16 비트 INT 값 (0-65535)이 있고 그 이상을 원하면 두 개의 16 비트 INT 값을 한 행에 사용하십시오. BYTE 값 (0-255)을 갖는 것으로 생각하지만 최대 99 자리의 값만 사용하십시오. 100에 도달하면 유용한 숫자만큼 다음 BYTE 값으로 롤오버하십시오. 오늘날의 GHZ 컴퓨터에서는 이와 같은 조잡한 코딩조차도 좋습니다.

물론 조금 더 빠른 대안이 있습니다.
숫자에 18을 반복적으로 더하면 간단히 2를 빼고 20을 더하는 것이 더 빠릅니다. 18, 36, 54, 72, 90, 108, ... 18 = 20 + (-2).
바이너리에서도 작동합니다. (이진수의 동일한 10 진수 값) 10010, 100100, 110110, 1001000
DEC (18) = BIN (10010)
이진 구문 분석이 더 쉬운 경우를 제외하고 18 = 16 + 2
DEC (16 + 2) = BIN (10000 + 00010). 값이 15 인 경우 이진수로 16을 더하고 1을 빼는 것으로 생각하십시오 (10000-00001).

이런 식으로 숫자 청크를 값당 관리 가능한 한계로 유지할 수 있습니다.
기본 16 비트 INT 값 (0 ~ 65535)을 4 자리 10 진수 제한 (0 ~ 9999)으로 제한하는 조잡한 코딩 방법을 사용하는 경우 값이 9999 제한을 초과하면됩니다. 9999를 빼고 다음 값 덩어리로 가져갑니다 (기본적으로 숫자와 실제 이진 계산으로 "추가 및 하위"를 수행하기 때문에).

이상적으로는 초등학교에서 배운 SYMBOLIC MATH를 사용하는 것이 가장 좋습니다. 어떻게 작동합니까? 소수점 이하 자릿수가 1이고 1을 더하면 소수점 이하 자릿수 2를 얻게됩니다. 이것을 심볼이라고 부르는 이유는 "IF 심볼 X (1)의 조회 테이블과 함께 임의의 심볼 계열을 사용할 수 있기 때문입니다. 기호 X (4)에 추가됩니다. THEN 출력 기호 X (5) ". 기호 X (1)는 고양이의 그림이 될 수 있고 기호 X (4)는 PERCENT 기호가 될 수 있지만 중요하지 않습니다. 당신은 당신의 상징, 어떤 일이 일어나는지에 대한 기본 규칙 책을 가지고 있으며 그 상징들이 결합되어 있습니다 (어린 시절에 암기 한 구구단과 같은 종류). Symbolic Math를 사용하면 프로세서의 숫자 제한을 실제로 호출하지 않고 무한한 자릿수를 추가 할 수 있습니다.

쉬운 코딩에서이 작업을 수행하는 한 가지 방법은 작업하려는 각 표현 된 숫자를 큰 차원 배열에서 단일 단위로 사용하는 것입니다. 10 진수 4096 (단위 상자 당 2 자리를 초과하지 않음)을 나타내려면 2 세트의 4096 BYTE 배열 위치를 할당하십시오. 1098874 값을 저장하면 배열을 (1) (0) (9) (8) (8) (7) (4)와 같이 활용할 수 있습니다. 7756 값을 추가 한 경우 (7) (7) (5) (6)으로 변환 한 다음 추가합니다. 결과는 (1) (0) (9) (15) (15) (12) (10)입니다. 그러면 모든 숫자 상자가 (0 ~ 9). 가장 오른쪽 (10) 값은 10을 빼고 결과 값은 0 (0)이되고 (1) 값은 (12)의 다음 왼쪽 상자로 이동하여 (13) 10을 갖습니다. (3)으로 빼기.


7
너무 많은 소리를 내기 위해 -1
Slipp D. Thompson

5
@Gridlock 님, 저는 여러분이 완전히 새로운 사용자라는 것을 알게되었습니다. 환영합니다. 본인의 공감대가 영구적이지 않다는 것을 분명히해야합니다. 그것은 건설적인 비판을위한 것입니다. 귀하가 제공 한 답변에 가치가 있으며, 귀하가 요청한 수정을 한 후에는 공의로 변경하여 기쁠 것입니다. 또한 SE는 포럼이 아닙니다. 좋은 대답은 읽히지 않고 잊혀지지 만 시간이 지남에 따라 배당금을 지불합니다. 여기에 답변을 수정하면 커뮤니티와 담당자에게 도움이됩니다. 나는 당신을 놀라게하지 않기를 바랍니다. 다시 한 번 환영합니다. 제 조언을 활용하시기 바랍니다.
Slipp D. Thompson

1
내가 제안 할 다른 제안은 모든 대문자 대신 기본 마크 다운 형식을 사용하는 것입니다. 텍스트를 백틱 ( `text`text)으로 줄 바꿈 하면 코드 간격, 함수 이름, 데이터 등에 적합합니다. 밑줄이나 별표로 텍스트를 줄이면 이탤릭체 ( _text_또는 *text*텍스트 ), 이중 밑줄 또는 이중 밑줄로 표시됩니다. 별표는 굵게 표시됩니다 ( __text__또는 **text**텍스트 ).
Slipp D. Thompson

0

당신이하는 일은 여러 변수를 결합한 다음 변수 사이의 더하기와 오버플로를 직접 제어하는 ​​것입니다. 그런 식으로 자릿수를 가질 수 있습니다. 10,000 개의 32 비트 정수를 결합하면 필요한 경우 32,000 비트의 숫자를 갖습니다. 프로그래밍 언어에는 제한이 없습니다. 유일한 한계는 당신이 알아낼 수있는 것입니다.


공감 한 사람들에게 왜 그런지 설명해 주시겠습니까? 이 인기있는 해결책이 아니라, 제로 노력이 필요 한 경우에도, 여전히 해결책, 그리고 당신은 언어 / 지원하지 않는 플랫폼에서 동일조차 할 수 있도록 수있는 하나 double또는 BigInteger.
TomTsagk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.