Interesting thing happening when I take a number, multiply it by 10, and then add 1 [duplicate]

StackOverflow https://stackoverflow.com/questions/21247174

Вопрос

static int fn = 0;
static int sn = 0;
static boolean running = false;
public static void run()
{
    while (running == true)
    {
        fn = numbers[0];
        sn = numbers[1];            
        if (sign == 0)
        {
            input.setText(String.valueOf(fn));
        }
    }
}
static class one implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        if (Display.sign == 0)
        {
            Display.numbers[0] = Display.numbers[0] *10;
            Display.numbers[0] = Display.numbers[0] +1;
        }
    }
}

This is the code for a calculator that I am programming (not all of it of course). This is the part where I display the number on the screen which I have done, but weirdly this works up until 10 characters

So after I get the program to display 1111111111 I want to do it once more and it gives me this weird number -1773790777. I am confused about how the program comes up with this. As you can see, above Display.numbers[] is the array I am storing the two numbers in. So to go over a place I multiply the number in the array by 10 then add 1. So how does this give me a negative number in the first place and what can I do to solve this problem?

Это было полезно?

Решение

Is your number overflowing?

You can check it by looking at Integer.MAX_VALUE (assuming you are using an integer). If you go over that you will loop will get weird results like this. See - http://javapapers.com/core-java/java-overflow-and-underflow/ for more details.

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

It's overflowing!

1111111111*10 + 1 = 11111111111 which is 0x2964619C7 in hexadecimal. It's a 34-bit value which can't be stored in a 32-bit int

In Java arithmetic operations wrap around by default, so if the result overflowed then it'll be wrapped back to the other end of the value range. See How does Java handle integer underflows and overflows and how would you check for it?

However due to the use of 2's complement, the result will be the lower bits of the result 11111111111 mod 232 = 2521176519 = 0x964619C7 which is -1'773'790'777 in 32-bit int, that's why you see the number. You should read more on binary, that's the basic of nowadays computers

In Java 8 you'll have an easier way to detect overflow with the new *Exact methods

The platform uses signed two's complement integer arithmetic with int and long primitive types. The developer should choose the primitive type to ensure that arithmetic operations consistently produce correct results, which in some cases means the operations will not overflow the range of values of the computation. The best practice is to choose the primitive type and algorithm to avoid overflow. In cases where the size is int or long and overflow errors need to be detected, the methods addExact, subtractExact, multiplyExact, and toIntExact throw an ArithmeticException when the results overflow. For other arithmetic operations such as divide, absolute value, increment, decrement, and negation overflow occurs only with a specific minimum or maximum value and should be checked against the minimum or maximum as appropriate.

https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top