Comment faire de l'arithmétique, + - / * % !, avec des nombres entiers arbitrairement grands sans utiliser java.math.BigInteger
?
Par exemple, la factorielle de 90 renvoie 0 en Java. J'aimerais être en mesure de résoudre ce problème.
Comment faire de l'arithmétique, + - / * % !, avec des nombres entiers arbitrairement grands sans utiliser java.math.BigInteger
?
Par exemple, la factorielle de 90 renvoie 0 en Java. J'aimerais être en mesure de résoudre ce problème.
texte fort public class BigInteger {
public static String checkSignWithRelational(int bigInt1, int bigInt2){
if( bigInt1 < 0){
return "negative";
}else {
return "positive";
}
}
BigInteger( long init)
{
Long.parseLong(bigInt1);
}
BigInteger String (String init){
return null;
}
private static int intLenght(int bigInt) {
return Integer.toString(bigInt).length();
}
private static int[] intToArray(int bigInt, int bigIntLength, int arrayLength) {
int array[] = new int[arrayLength ];
for (int i = 0; i < arrayLength ; i++) {
array[i] = ( i<bigIntLength ?
getDigitAtIndex(bigInt, bigIntLength - i -1) :0 );
}
return array;
}
static String add(int bigInt1, int bigInt2) {
//Find array length
int length1 = intLenght(bigInt1);
int length2 = intLenght(bigInt2);
int arrayLength = Math.max(length1, length2);
int array1[] = intToArray(bigInt1, length1, arrayLength);
int array2[] = intToArray(bigInt2, length2, arrayLength);
return add(array1, array2);
}
private static String add(int[] array1, int[] array2) {
int carry=0;
int addArray[] = new int[array1.length + 1];
for (int i = 0; i < array1.length; i++) {
addArray[i] = (array1[i] + array2[i] + carry) % 10 ;
carry = (array1[i] + array2[i] + carry) / 10;
}
addArray[array1.length] = carry;
return arrayToString(addArray);
}
private static int getDigitAtIndex(int longint,int index){
return Integer.parseInt(Integer.toString(longint).substring(index, index+1));
}
private static String arrayToString(int[] addArray) {
String add = "";
boolean firstNonZero = false;
for (int i = addArray.length-1; i >= 0 ; i--) {
if(!firstNonZero && (addArray[i]==0)){
continue;
} else{
firstNonZero=true;
}
add += addArray[i];
if((i%3 ==0)&&i!=0){ add +=",";} //formatting
}
String sumStr = add.length()==0?"0":add;
return sumStr;
}
public static String sub(int bigInt1, int bigInt2) {
int length1 = intLenght(bigInt1);
int length2 = intLenght(bigInt2);
int arrayLength = Math.max(length1, length2);
int array1[] = intToArray(bigInt1, length1, arrayLength);
int array2[] = intToArray(bigInt2, length2, arrayLength);
return sub(array1, array2);
}
private static String sub(int[] array1, int[] array2) {
int carry=0;
int sub[] = new int[array1.length + 1];
for (int i = 0; i < array1.length; i++) {
sub[i] = (array1[i] - array2[i] + carry) % 10 ; //sum digits + carry; then extract last digit
carry = (array1[i] - array2[i] + carry) / 10; //Compute carry
}
sub[array1.length] = carry;
return arrayToString(sub);
}
public static String mul(int bigInt1, int bigInt2) {
int length1 = intLenght(bigInt1), length2 = intLenght(bigInt2), length = Math.max(length1, length2);
int array1[] = intToArray(bigInt1, length1, length); int array2[] = intToArray(bigInt2, length2, length);
return mul(array1, array2);
}
private static String mul(int[] array1, int[] array2) {
int product[] = new int[array1.length + array2.length];
for(int i=0; i<array1.length; i++){
for(int j=0; j<array2.length; j++){
int prod = array1[i] * array2[j];
int prodLength = intLenght(prod);
int prodAsArray[] = intToArray(prod, prodLength, prodLength);
for (int k =0; k < prodAsArray.length; k++) {
product[i+j+k] += prodAsArray[k];
int currentValue = product[i+j+k];
if(currentValue>9){
product[i+j+k] = 0;
int curValueLength = intLenght(currentValue);
int curValueAsArray[] = intToArray(currentValue, curValueLength, curValueLength);
for (int l = 0; l < curValueAsArray.length; l++) {
product[i+j+k+l] += curValueAsArray[l];
}
}
}
}
}
return arrayToString(product);
}
public static int div(int bigInt1, int bigInt2) {
if ( bigInt2 == 0){
throw new ArithmeticException("Division by 0 is undefined:" + bigInt1+ "/" + bigInt2);
}
int sign = 1;
if(bigInt1 < 0) {
bigInt1 = -bigInt1;
sign = -sign;
}
if (bigInt2 < 0){
bigInt2 = -bigInt2;
sign = -sign;
}
int result =0;
while (bigInt1 >= 0){
bigInt1 -= bigInt2;
result++;
}
return (result - 1) * sign;
}
public static String check(String bigInt1, String bigInt2){
int difference;
StringBuilder first = new StringBuilder(bigInt1);
StringBuilder second = new StringBuilder(bigInt2);
if(bigInt1.length()> bigInt2.length()){
difference = bigInt1.length() - bigInt2.length();
for(int x = difference; x > 0; x--){
second.insert(0,"0");
}
bigInt2 = second.toString();
return bigInt2;
}else {
difference = bigInt2.length() - bigInt1.length();
for (int x = difference; x> 0; x--)
{
first.insert(0, "0");
}
bigInt1 = first.toString();
return bigInt1;
}
}
public static int mod(int bigInt1, int bigInt2){
int res = bigInt1 % bigInt2;
return (res);
}
public static void main(String[] args) {
int bigInt1 = Integer.parseInt("987888787");
int bigInt2 = Integer.parseInt("444234343");
System.out.println(bigInt1+" + "+bigInt2+" = "+add(bigInt1, bigInt2));
System.out.println(bigInt1+" - "+bigInt2+" = "+sub(bigInt1, bigInt2));
System.out.println(bigInt1+" * "+bigInt2+" = "+mul(bigInt1, bigInt2));
System.out.println(bigInt1+" / "+bigInt2+" = "+div(bigInt1, bigInt2));
System.out.println(bigInt1+" % "+bigInt2+" = "+mod(bigInt1, bigInt2));
}
}
Si nous avons de très grands nombres sur lesquels nous voulons effectuer des opérations arithmétiques, ils doivent être sous une forme objet telle que les chaînes de caractères.
Qu'ils soient des chaînes de caractères dont la longueur est supérieure à la plage de BigInteger.
Dans ce cas, je vais effectuer des opérations arithmétiques comme nous le faisons sur un ordinateur portable. Par exemple - Supposons que nous devions faire une addition. Commencez par comparer la longueur des deux chaînes de caractères. Créez trois nouvelles chaînes. La première chaîne est la plus petite. La deuxième chaîne est la sous-chaîne la plus à droite de la chaîne la plus longue dont la longueur est égale à celle de la chaîne la plus petite. La troisième chaîne est la longue chaîne restante du côté gauche. Maintenant, ajoutez la première et la deuxième chaîne depuis la fin en convertissant les caractères en nombres entiers, un caractère à la fois et en conservant le report dans une variable int. Immédiatement après chaque addition, ajoutez la somme dans un StringBuffer. Après l'addition des deux chaînes de caractères, effectuez la même opération pour la troisième chaîne et continuez à ajouter la retenue. À la fin, inversez le StringBuffer et renvoyez la chaîne.
Voici le code que j'ai utilisé pour l'addition
public String addNumber(String input1,String input2){
int n=0;String tempStr;
String one="";
String two="";
if(input1.length()>input2.length()){
n=input1.length()-input2.length();
tempStr=new String(input1);
one=new String(input1.substring(n,input1.length()));
two=new String(input2);
}else{
n=input2.length()-input1.length();
tempStr=new String(input2);
one=new String(input2.substring(n,input2.length()));
two=new String(input1);
}
StringBuffer temp=new StringBuffer();
for(int i=0;i<n;i++){
temp.append(tempStr.charAt(i));
}
StringBuffer newBuf=new StringBuffer();
int carry=0;
int c;
for(int i=one.length()-1;i>=0;i--){
int a=Character.getNumericValue(one.charAt(i));
int b=Character.getNumericValue(two.charAt(i));
c=a+b+carry;
newBuf.append(""+(c%10));
c=c/10;
carry=c%10;
}
String news=new String(temp);
for(int i=news.length()-1;i>=0;i--){
c=(Character.getNumericValue(news.charAt(i)))+carry;
newBuf.append(""+(c%10));
c=c/10;
carry=c%10;
}
if(carry==1){
newBuf.append(""+carry);
}
String newisis=new String(newBuf.reverse());
return newisis;
}
Essayez bigNumber .
http://nishi-inc.github.io/bigNumber
Il s'agit d'une bibliothèque binaire pour Java qui affirme ne pas avoir de problèmes avec les nombres BigInteger et BigDecimal. Elle les unit.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
3 votes
Pourquoi voudriez-vous le remplacer ?
28 votes
s/How/Why/
et vous avez une bonne question.0 votes
Des nombres allant jusqu'à 600 chiffres, en gros aussi grands que l'on veut.
0 votes
Vous souhaitez créer votre propre bibliothèque ?
0 votes
Pas nécessairement. Je pense que je voudrai convertir les nombres en binaire car l'arithmétique binaire est beaucoup plus facile. Mais les convertir sera la partie la plus difficile.
3 votes
@frodosamoa : 600 c'est beaucoup trop petit. Les personnes qui cherchent de grands nombres premiers ont besoin de millions de chiffres.
1 votes
Vous pourriez copier le code de BigInteger, en supprimant tout ce que vous voulez éviter. Cependant, il est peu probable que vous y gagniez quoi que ce soit et certaines JVM fournissent des optimisations de manipulation spéciales pour BigInteger/BigDecimal dont une copie de la classe ne profitera probablement pas. Je lirais au moins le code de BigInteger avant d'essayer ceci car il contient tout le code dont vous semblez avoir besoin.
1 votes
En fonction de votre problème, vous pouvez utiliser un langage de script ou un langage jvm différent. Scala possède un type BigInt avec des opérateurs surchargés.
1 votes
@frodosamoa modifier votre question que vous cherchez bibliothèque pour compter >600 chiffres
1 votes
@John : Je suppose qu'une meilleure façon de le reformuler est que je veux être capable de faire de l'arithmétique que Java ne peut normalement pas faire, comme 90 ! @Peter Lawrey : Hmm. Je pense que cela va beaucoup nous aider. Merci !
1 votes
L'idée de base est de stocker des valeurs int de 32 bits et d'effectuer des opérations longues sur celles-ci. De cette façon, vous pouvez stocker des valeurs non signées de 32 bits et effectuer efficacement des opérations +, - et * sans débordement. La conversion de texte en binaire est juste un processus de multiplication et d'addition pour chaque chiffre. La conversion du binaire en texte est une division et un modulus pour obtenir chaque chiffre.
4 votes
La factorielle (int)(34) == 0, la factorielle (long)(66) == 0, si vous ne prenez que les derniers bits d'un grand nombre, vous ne devez pas vous attendre à obtenir la bonne réponse. Ce sujet a été récemment abordé dans stackoverflow.com/questions/5317732/