I want it to crash

Given the following piece of C code:

1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    if(argc != 3 || !atoi(argv[2]))
        return 1;
    return abs(atoi(argv[1])) / atoi(argv[2]);
}

determine the set of inputs that will lead to a SIGFPE (floating point exception) being triggered.


Answer format:

Since it is possible for either input to be a negative number, and there is no way to input text as answer. The best I can get is to concatenate the inputs, and then encode the result with this .

For example, if argv[1] = 13, argv[2] = -37 , then you should encode 13-37 in the provided link, and your answer should be 4951455155 .


Note:

This is not an original challenge. I found it somewhere and think most people probably have not seen this before, so I would like to share it here. More specifically, if you are interested, visit here .

I will not submit a solution for now, as I hope you can take your time to think through and do some research about this challenge. If someone solved this and wants to share a solution, please feel free to do so.


Edit: I will put up the solution in a week if no one manages to solve this.

Edit 2: I've posted a solution. Sorry for the delay.


The answer is 45504952555256515452564549.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

1 solution

Daniel Lim
Jul 13, 2017

Short solution

As we see here , INT_MIN = 2147483648 / 1 =-2147483648/-1 yields a SIGFPE signal.

Long solution

But, why does that particular combination give us an error. First we need to understand how 2's complement work.

2's complement

In our everyday lives, we deal with negative numbers, in various scenarios like owing someone money, temperature below 0 degrees, and more. It's easy for us, we just prepend a minus sign to the front of the number. But, how does a computer store negative numbers?

The following examples will be shown in a 4-bit binary representation (using only 4 bits to represent a binary number).

First, we need to know what's the 1's complement. Simply put, it's just the result of flipping all the bits of a number. For example, we have 7 7 , whose binary representation is 0111 0111 , hence in a 4-bit binary representation, we can store 7 -7 as its 1's complement, which is 1000 1000 . Another example is if we have 5 -5 , whose binary representation is 1010 1010 in a 4-bit binary representation, we can get 5 5 as its 1's complement, 0101 0101 .

As a result, if our most significant bit (leftmost bit) is equal to 1 1 it is a negative number and, and in a n-bit binary representation our maximum value is 2 n 1 1 2^{n-1}-1 , while our minimum value is 2 n 1 -2^{n-1} .

So far so good, we are able to now store and distinguish between positive and negative numbers. However, we have a new problem. Notice that 0 in a 4-bit binary representation is equal to 0000 0000 , but what about its 1's complement? It's 1111 1111 .

It does not make any sense. If we were to compare these two binary numbers, they should have the same value, which is 0 0 , but here we can see that 0 0 and 0 -0 have different binary values. This poses a problem for us as we need to perform extra checks every time we compare between 0 0 and 0 -0 , rendering the system to be less efficient.

To solve this problem, we simply add 1 1 to the 1's complement, and that's our 2's complement. We have 5 -5 to be stored as the 2's complement of 5 10 = 010 1 2 5_{10}=0101_2 , so 5 10 = 101 0 2 + 1 2 = 101 1 2 -5_{10}=1010_2+1_2=1011_2 , and 0 10 = 111 1 2 + 1 2 = 1000 0 2 = 000 0 2 -0_{10}=1111_2+1_2=10000_2=0000_2 (note that we are using a 4-bit binary representation so the extra bit was truncated).

INT_MIN

If you remember from earlier, there is a maximum and minimum value for storing integers. For integer in particular, we have 4 4 bytes, which is 32 32 bits, whose minimum value is 2 32 1 = 2147483648 -2^{32-1}=-2147483648 and the maximum value is 2 32 1 1 = 2147483647 2^{32-1}-1=2147483647 .

From here, we can see that 2147483648 1 = 2147483648 \frac{-2147483648}{-1}=2147483648 , which exceeds the maximum value of an integer. This causes there to be an integer overflow which triggers SIGFPE.

Note: A more proper/rigorous solution involves looking at abs() and seeing what it does to our number, that causes an integer overflow to occur. I'll leave it to you to read up.

Wow, I never thought of this!

What could we possibly do to prevent this error?

Agnishom Chattopadhyay - 3 years, 11 months ago

I think the best would be to perform checks before a division or modulus operation that uses values provided by the user.

Daniel Lim - 3 years, 11 months ago

1 pending report

Vote up reports you agree with

×

Problem Loading...

Note Loading...

Set Loading...