Мое задание просит нас попросить пользователя ввести число и распечатать его факториал,
он также просит нас не позволять пользователю выбирать любое отрицательное число или число больше 25, когда они это делают, мы возвращаем их обратно к сканеру, чтобы повторно получить номер.
нам также сказали хранить число в длинном, но когда я это делаю, если пользователь вводит число больше 20 и =<25, ответ становится отрицательным, вызывая длинное переполнение.
Я попытался изменить long на BigInteger, но когда я продолжаю получать сообщение об ошибке в каждой строке, я использую BigInteger вместо long
boolean correctInputn= false;
while(!correctInputn)
{
long number;// declares variables for storing number
long factorial = 1;// declare variable for storing factorial
System.out.println("Enter a number between 1 and 25"); // tells user to enter number
number = scanner.nextLong();
if (number <0)
{System.out.println("Positive numbers only");// if number entered is negative
correctInputn = false; continue;} // if user enters number less than 0 loops back to code start
else if (number > 25)
{ System.out.println("Number to large to print");
correctInputn = false; continue;} // if user enters number over 25 loops back to code start
else {
// if user enter 10, counter starts at 10 and runs to two
for(long mynumber = number; mynumber >= 1; mynumber--) {
factorial = factorial*mynumber; // mynumber would contain different values and that is multiplied by value present in factorial value and stored again in factorial variable
}
System.out.println("The factorial of " + number +" is equal to " + factorial);
break;
}
}
И когда вы публикуете свой код с помощью BigInteger
, пожалуйста, делайте отступы должным образом. Это помогает удобочитаемости больше, чем вы думаете, для тех, кто не писал код. Ваша IDE может сделать это за вас.
BigInteger
— это ссылочный тип, как и все типы в java, за исключением жестко заданного списка long
, int
, double
, short
, float
, char
, byte
и boolean
. Вы можете вызывать методы на нем. +
можно использовать, если элемент слева от него имеет тип String
, который будет вызывать toString()
для них и объединять их. Вот и все. Они не «поддерживают» -, +, * и так далее. Вместо этого у них есть методы .multiply
и .add
и друзья. Обратите внимание, что это не добавляет число к объекту, оно вычисляет значение и возвращает его, например. вы бы написали factorial = factorial.multiply(myNumber)
. Вам придется заменить все операторы соответствующим методом, и вам придется превратить все числа в объекты BigInteger
, используя, например, BigInteger.valueOf(20)
.
Вы не можете волшебным образом предотвратить переполнение longs. Это фундаментальный аспект математики на 64-битных числах: вы не можете хранить более 2^64 разных вещей в 64-битах по той же причине 1+1=2 — из-за фундаментальных математических причин.
Это полезно, подробно и точно без какой-либо ложной подачи. Большое спасибо.
**I FOUND A SOLUTION AND NOW IT DOESNT OVERFLOW**
**MAIN**
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Factorial factNum;
Scanner in = new Scanner(System.in);
boolean flagCheck = false;
System.out.println("Please give a number between 0 - 25: ");
factNum = new Factorial(in.nextLong());
//check if the number is in the limits
while(!flagCheck) {
if (factNum.getVarForFact() < 0){
System.out.println("Number must be over 0. Please enter again a
number between 0-25");
factNum = new Factorial(in.nextLong());
} else if (factNum.getVarForFact() > 25){
System.out.println("Number must be under 25. Please enter again a
number between 0-25");
factNum = new Factorial(in.nextLong());
} else if (factNum.getVarForFact() == 0) {
factNum.setFinalFact(1);
System.out.println("The factorial of " + factNum.getVarForFact() + "
is " + factNum.getFinalFact());
flagCheck = true;
} else{
factNum.factorial();
System.out.println("The factorial of " + factNum.getVarForFact() + "
is " + factNum.getFactorial());
flagCheck = true;
}
}
}
}
ФАКТОРНЫЙ КЛАСС
import java.math.BigInteger;
class Factorial {
//variable for storing the given number and find the factorial
private long varForFact;
private long finalFact;
private BigInteger factorial = BigInteger.ONE;
//Constructor
Factorial(long varForFact){
this.varForFact = varForFact;
}
//Getter
public long getVarForFact(){
return this.varForFact;
}
public long getFinalFact() {
return finalFact;
}
public BigInteger getFactorial() {
return factorial;
}
//Setter
public void setVarForFact(long varForFact){
this.varForFact = varForFact;
}
public void setFinalFact(long finalFact) {
this.finalFact = finalFact;
}
//factorial method, it will return the factorial
public void factorial(){
for (long i = this.varForFact; i > 0; i--) {
this.factorial = this.factorial.multiply(BigInteger.valueOf(i));
}
}
}
Голосование против исходило не от меня. Он уже был там, когда я увидел этот ответ. Я был удивлен и не могу этого объяснить. Возможно, кому-то еще не понравился тот факт, что вы опубликовали второй ответ, но я все еще не вижу, чтобы это оправдывало отрицательный голос.
Вы не можете предотвратить переполнение
long
, BigInteger - это ответ, пожалуйста, опубликуйте свой код, используя его. Для BigInteger вы использовали методmultiply
вместо оператора*
.