Десятичная основа использует 0 ... 9 (10 цифр) для представления цифр, число, которое находится во второй позиции справа налево, представляет Digits * base.length ^ l2rPosition. Используя эту логику, вы можете создать класс, который «в значительной степени выполняет то, что сказал вам учитель начальной школы, когда мы использовали бумагу для вычислений, но с числом baseN и преобразованиями от основания к основанию». Я выполнил этот класс полностью функционален на C #, но у меня нет времени полностью переводить его на java, это примерно та же логика, что и java.math.BigInteger. (с меньшей производительностью, держу пари, я использовал много списков> _> "Нет времени оптимизировать его сейчас
class IntEx {
ArrayList<Integer> digits = new ArrayList<>();
long baseSize = Integer.MAX_VALUE+1;
boolean negative = false;
public IntEx(int init)
{
set(init);
}
public void set(int number)
{
digits = new ArrayList<>();
int backup = number;
do
{
int index = (int)(backup % baseSize);
digits.add(index);
backup = (int) (backup / baseSize);
} while ((backup) > 0);
}
// ... other operations
private void add(IntEx number)
{
IntEx greater = number.digits.size() > digits.size() ? number : this;
IntEx lesser = number.digits.size() < digits.size() ? number : this;
int leftOvers = 0;
ArrayList<Integer> result = new ArrayList<>();
for (int i = 0; i < greater.digits.size() || leftOvers > 0; i++)
{
int sum;
if (i >= greater.digits.size())
sum = leftOvers;
else if(i >= lesser.digits.size())
sum = leftOvers + greater.digits.get(i);
else
sum = digits.get(i) + number.digits.get(i) + leftOvers;
leftOvers = 0;
if (sum > baseSize-1)
{
while (sum > baseSize-1)
{
sum -= baseSize;
leftOvers += 1;
}
result.add(sum);
}
else
{
result.add(sum);
leftOvers = 0;
}
}
digits = result;
}
private void multiply(IntEx target)
{
ArrayList<IntEx> MultiParts = new ArrayList<>();
for (int i = 0; i < digits.size(); i++)
{
IntEx thisPart = new IntEx(0);
thisPart.digits = new ArrayList<>();
for (int k = 0; k < i; k++)
thisPart.digits.add(0);
int Leftovers = 0;
for (int j = 0; j < target.digits.size(); j++)
{
int multiFragment = digits.get(i) * (int) target.digits.get(j) + Leftovers;
Leftovers = (int) (multiFragment / baseSize);
thisPart.digits.add((int)(multiFragment % baseSize));
}
while (Leftovers > 0)
{
thisPart.digits.add((int)(Leftovers % baseSize));
Leftovers = (int) (Leftovers / baseSize);
}
MultiParts.add(thisPart);
}
IntEx newNumber = new IntEx(0);
for (int i = 0; i < MultiParts.size(); i++)
{
newNumber.add(MultiParts.get(i));
}
digits = newNumber.digits;
}
public long longValue() throws Exception
{
int position = 0;
long multi = 1;
long retValue = 0;
if (digits.isEmpty()) return 0;
if (digits.size() > 16) throw new Exception("The number within IntEx class is too big to fit into a long");
do
{
retValue += digits.get(position) * multi;
multi *= baseSize;
position++;
} while (position < digits.size());
return retValue;
}
public static long BaseConvert(String number, String base)
{
boolean negative = number.startsWith("-");
number = number.replace("-", "");
ArrayList<Character> localDigits = new ArrayList<>();
for(int i = number.toCharArray().length - 1; i >=0; i--) {
localDigits.add(number.charAt(i));
}
// List<>().reverse is missing in this damn java. -_-
long retValue = 0;
long Multi = 1;
char[] CharsBase = base.toCharArray();
for (int i = 0; i < number.length(); i++)
{
int t = base.indexOf(localDigits.get(i));
retValue += base.indexOf(localDigits.get(i)) * Multi;
Multi *= base.length();
}
if (negative)
retValue = -retValue;
return retValue;
}
public static String BaseMult(String a, String b, String Base)
{
ArrayList<String> MultiParts = new ArrayList<>();
// this huge block is a tribute to java not having "Reverse()" method.
char[] x = new char[a.length()];
char[] y = new char[b.length()];
for(int i = 0; i < a.length(); i++) {
x[i] = a.charAt(a.length()-i);
}
for(int i = 0; i < b.length(); i++) {
y[i] = a.charAt(a.length()-i);
}
a = new String(x);
b = new String(y);
// ---------------------------------------------------------------------
for (int i = 0; i < a.length(); i++)
{
ArrayList<Character> thisPart = new ArrayList<>();
for (int k = 0; k < i; k++)
thisPart.add(Base.charAt(0));
int leftOvers = 0;
for (int j = 0; j < b.length(); j++)
{
// Need I say repeated characters in base may cause mayhem?
int MultiFragment = Base.indexOf(a.charAt(i)) * Base.indexOf(b.charAt(j)) + leftOvers;
leftOvers = MultiFragment / Base.length();
thisPart.add(Base.charAt(MultiFragment % Base.length()));
}
while (leftOvers > 0)
{
thisPart.add(Base.charAt(leftOvers % Base.length()));
leftOvers = leftOvers / Base.length();
}
char[] thisPartReverse = new char[thisPart.size()];
for(int z = 0; z < thisPart.size();z++)
thisPartReverse[z] = thisPart.get(thisPart.size()-z);
MultiParts.add(new String(thisPartReverse));
}
String retValue = ""+Base.charAt(0);
for (int i = 0; i < MultiParts.size(); i++)
{
retValue = BaseSum(retValue, MultiParts.get(i), Base);
}
return retValue;
}
public static String BaseSum(String a, String b, String Base)
{
// this huge block is a tribute to java not having "Reverse()" method.
char[] x = new char[a.length()];
char[] y = new char[b.length()];
for(int i = 0; i < a.length(); i++) {
x[i] = a.charAt(a.length()-i);
}
for(int i = 0; i < b.length(); i++) {
y[i] = a.charAt(a.length()-i);
}
a = new String(x);
b = new String(y);
// ---------------------------------------------------------------------
String greater = a.length() > b.length() ? a : b;
String lesser = a.length() < b.length() ? a : b;
int leftOvers = 0;
ArrayList<Character> result = new ArrayList();
for (int i = 0; i < greater.length() || leftOvers > 0; i++)
{
int sum;
if (i >= greater.length())
sum = leftOvers;
else if (i >= lesser.length())
sum = leftOvers + Base.indexOf(greater.charAt(i));
else
sum = Base.indexOf(a.charAt(i)) + Base.indexOf(b.charAt(i)) + leftOvers;
leftOvers = 0;
if (sum > Base.length()-1)
{
while (sum > Base.length()-1)
{
sum -= Base.length();
leftOvers += 1;
}
result.add(Base.charAt(sum));
}
else
{
result.add(Base.charAt(sum));
leftOvers = 0;
}
}
char[] reverseResult = new char[result.size()];
for(int i = 0; i < result.size(); i++)
reverseResult[i] = result.get(result.size() -i);
return new String(reverseResult);
}
public static String BaseConvertItoA(long number, String base)
{
ArrayList<Character> retValue = new ArrayList<>();
boolean negative = false;
long backup = number;
if (negative = (backup < 0))
backup = -backup;
do
{
int index = (int)(backup % base.length());
retValue.add(base.charAt(index));
backup = backup / base.length();
} while ((backup) > 0);
if (negative)
retValue.add('-');
char[] reverseRetVal = new char[retValue.size()];
for(int i = 0; i < retValue.size(); i++)
reverseRetVal[i] = retValue.get(retValue.size()-i);
return new String(reverseRetVal);
}
public String ToString(String base)
{
if(base == null || base.length() < 2)
base = "0123456789";
ArrayList<Character> retVal = new ArrayList<>();
char[] CharsBase = base.toCharArray();
int TamanhoBase = base.length();
String result = ""+base.charAt(0);
String multi = ""+base.charAt(1);
String lbase = IntEx.BaseConvertItoA(baseSize, base);
for (int i = 0; i < digits.size(); i++)
{
String ThisByte = IntEx.BaseConvertItoA(digits.get(i), base);
String Next = IntEx.BaseMult(ThisByte, multi, base);
result = IntEx.BaseSum(result, Next, base);
multi = IntEx.BaseMult(multi, lbase, base);
}
return result;
}
public static void main(String... args) {
int ref = 0;
IntEx result = new IntEx(0);
while(++ref <= 1000)
{
IntEx mul = new IntEx(1000);
for (int i = 0; i < 1000; ++i) {
mul.multiply(new IntEx(i));
}
result.add(mul);
}
System.out.println(result.toString());
}
}
Отказ от ответственности: это приблизительный перевод / локализация из исследования C #, в нем много опущенного кода. Это "почти" та же логика, что и java.math.BigInteger (вы можете открыть код BigInteger в своем любимом конструкторе и проверить себя. Если можно, я забываю перегруженный оператор, не переведенный на java, проявите немного терпения и прощения. , этот пример предназначен только для пояснения теории "возможно".
Кроме того, просто отступление, я знаю, что это «Пытаюсь изобрести велосипед», но, учитывая, что этот вопрос имеет академическую цель, я думаю, что его довольно разумно поделиться. Результат этого исследования можно увидеть на gitHub (хотя он не локализован), я не расширяю этот C # код здесь для его очень обширного, а не языка этого вопроса.
person
Felype
schedule
16.04.2015
long
подойдет;int
просто нет. - person Joop Eggen   schedule 16.04.2015n*sizeOfBase^pos
, являющееся единичным значением цифры, sizeOfBase 10 в этом case и pos его позиция 0-индексируется справа налево. Конечное число - это сумма относительных значений каждой цифры. Теперь возьмите эту логику и сделайте sizeOfBase = Integer.MAX_VALUE, используйте массив целых чисел для представления цифр и вуаля. Вы заново изобрелиjava.math.BigInteger
, возможно, неуклюже, но все же. - person Felype   schedule 16.04.2015