Как предотвратить длительное переполнение?

Мое задание просит нас попросить пользователя ввести число и распечатать его факториал,

он также просит нас не позволять пользователю выбирать любое отрицательное число или число больше 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;
    }
    }

Вы не можете предотвратить переполнение long, BigInteger - это ответ, пожалуйста, опубликуйте свой код, используя его. Для BigInteger вы использовали метод multiply вместо оператора *.

f1sh 20.11.2022 12:29

И когда вы публикуете свой код с помощью BigInteger, пожалуйста, делайте отступы должным образом. Это помогает удобочитаемости больше, чем вы думаете, для тех, кто не писал код. Ваша IDE может сделать это за вас.

Ole V.V. 20.11.2022 12:51
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Как включить TLS в gRPC-клиенте и сервере : 2
Как включить TLS в gRPC-клиенте и сервере : 2
Здравствуйте! 🙏🏻 Надеюсь, у вас все хорошо и добро пожаловать в мой блог.
Сортировка hashmap по значениям
Сортировка hashmap по значениям
На Leetcode я решал задачу с хэшмапой и подумал, что мне нужно отсортировать хэшмапу по значениям.
Принципы SOLID - лучшие практики
Принципы SOLID - лучшие практики
SOLID - это аббревиатура, обозначающая пять ключевых принципов проектирования: принцип единой ответственности, принцип "открыто-закрыто", принцип...
gRPC на Android с использованием TLS
gRPC на Android с использованием TLS
gRPC - это относительно новая концепция взаимодействия между клиентом и сервером, но не более.
0
2
112
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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 — из-за фундаментальных математических причин.

Это полезно, подробно и точно без какой-либо ложной подачи. Большое спасибо.

Ole V.V. 20.11.2022 12:57
**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));
        }
    }
}

Голосование против исходило не от меня. Он уже был там, когда я увидел этот ответ. Я был удивлен и не могу этого объяснить. Возможно, кому-то еще не понравился тот факт, что вы опубликовали второй ответ, но я все еще не вижу, чтобы это оправдывало отрицательный голос.

Ole V.V. 21.11.2022 07:14

Другие вопросы по теме