Roman Kudryashov
Roman Kudryashov

Reputation: 91

Try/Catch Underflow and Overflow Exceptions

Need to utilize Underflow and Overflow exceptions using Try/Catch to pass the tests. There are series of tests that need to pass testing inputs that are outside of the bounds of the array.

Here is the code that is provided to me. I have to modify the SmartArray class. The Program class contains all the tests I need to pass.

using System;

namespace SmartArray_Test {

class UnderflowException : Exception
{
    public UnderflowException(string s) : base(s) { }
}
class OverflowException : Exception
{
    public OverflowException(string s) : base(s) { }
}

class SmartArray
{
    int[] rgNums;

    public SmartArray()
    {
        rgNums = new int[5];
    }
    public SmartArray(int howMany)
    {
        rgNums = new int[howMany];
    }

    public void SetAtIndex(int idx, int val)
    {
        try
        {
            rgNums[idx]=val;
        }
        catch (UnderflowException Exception)
        {

            Console.WriteLine(Exception.Message);
        }
        catch (OverflowException Exception)
        {
            Console.WriteLine(Exception.Message);
        }
    }

    public int GetAtIndex(int idx)
    {
        try
        {
            return rgNums[idx];

        }
        catch (UnderflowException Exception)
        {
            Console.WriteLine(Exception.Message);
        }
        catch (OverflowException Exception) 
        {    
            Console.WriteLine(Exception.Message);
        }
        return 0;
    }

    public void PrintAllElements()
    {
        for (int i = 0; i < rgNums.Length; i++)
            Console.WriteLine(rgNums[i]);
    }

    public bool Find(int val)
    {
        for (int i = 0; i < rgNums.Length; i++)
        {
            if (rgNums[i] == val)
                return true;
        }
        return false;
    }

}


class Program
{
    static void Main(string[] args)
    {
        SmartArray sa = new SmartArray();
        const int SMART_ARRAY_SIZE = 5;
        bool testPassed = false;

        Console.WriteLine("CHECK THIS: SmartArray starts with all zeros");
        sa.PrintAllElements();
        Console.WriteLine("\n*******************\n");

        try 
        {
            Console.WriteLine("================= SetAtIndex =================");
            Console.WriteLine("AutoChecked: Can add at slot 0?");
            sa.SetAtIndex(0, 10);
            Console.WriteLine("Test Passed: Able to set element 0!");
        }
        catch(Exception e)
        {
            Console.WriteLine("TEST FAILED: UNABLE TO SET ELEMENT 0!");
            Console.WriteLine(e.Message);
        }
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Can add at slots 0-4?");
        testPassed = true;
        for (int i = 0; i < SMART_ARRAY_SIZE; i++)
        {
            try
            {
                sa.SetAtIndex(i, 10 * i);
            }
            catch (Exception e)
            {
                Console.WriteLine("TEST FAILED: UNABLE TO SET ELEMENT {0}!", i);
                Console.WriteLine(e.Message);
                testPassed = false;
                break; // out of the loop
            }
        }
        if (testPassed)
            Console.WriteLine("Test Passed: Able to set all elements!");
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to add at slot {0}?", SMART_ARRAY_SIZE);

        try
        {
            sa.SetAtIndex(SMART_ARRAY_SIZE, 10);
            Console.WriteLine("TEST FAILED: SET ELEMENT {0} DID NOT OVERFLOW (but should have)", SMART_ARRAY_SIZE);
        }
        catch (OverflowException e)
        {
            Console.WriteLine("Test Passed: Unable to set element {0}!", SMART_ARRAY_SIZE);
        }
        catch (Exception e)
        {
            Console.WriteLine("TEST FAILED: SET ELEMENT {0} FAILED, BUT FOR THE WRONG REASON", SMART_ARRAY_SIZE);
            Console.WriteLine(e.Message);
        }
        Console.WriteLine("\n*******************\n");


        Console.WriteLine("AutoChecked: Should NOT be able to add at slot {0}?", SMART_ARRAY_SIZE + 10);
        try 
        {
            sa.SetAtIndex(SMART_ARRAY_SIZE + 10, 10);
            Console.WriteLine("TEST FAILED: SET ELEMENT {0} DIDN'T OVERFLOW", SMART_ARRAY_SIZE + 10);
        }                  
        catch (OverflowException e)
        {
            Console.WriteLine("Test Passed: Unable to set element {0}!", SMART_ARRAY_SIZE);
        }
        catch (Exception e)
        {
            Console.WriteLine("TEST FAILED: SET ELEMENT {0} FAILED, BUT FOR THE WRONG REASON", SMART_ARRAY_SIZE);
            Console.WriteLine(e.Message);
        }
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to add at slot -1?");
        try 
        {
            sa.SetAtIndex(-1, 10);
            Console.WriteLine("TEST FAILED: SET ELEMENT -1 DIDN'T UNDERFLOW");
        }                  
        catch (UnderflowException e)
        {
            Console.WriteLine("Test Passed: Unable to set element -1!");
        }
        catch (Exception e)
        {
            Console.WriteLine("TEST FAILED: SET ELEMENT -1 FAILED, BUT FOR THE WRONG REASON");
            Console.WriteLine(e.Message);
        }
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to add at slot -10?");
        try
        {
            sa.SetAtIndex(-10, 10);
            Console.WriteLine("TEST FAILED: SET ELEMENT -10 DIDN'T UNDERFLOW");
        }
        catch (UnderflowException e)
        {
            Console.WriteLine("Test Passed: Unable to set element -10!");
        }
        catch (Exception e)
        {
            Console.WriteLine("TEST FAILED: SET ELEMENT -10 FAILED, BUT FOR THE WRONG REASON");
            Console.WriteLine(e.Message);
        }
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("CHECK THIS: Should see 0, 10, 20, 30, 40");
        sa.PrintAllElements();
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("================= GetAtIndex =================");
        int valueGotten;
        Console.WriteLine("AutoChecked: Can get from slot 0?");
        try
        {
            valueGotten = sa.GetAtIndex(0);
            if (valueGotten != 0)
            {
                Console.WriteLine("TEST FAILED: UNEXPECTED VALUE FROM SLOT 0: (EXPECTED 0, GOT {0})", valueGotten);
            }
            else
                Console.WriteLine("Test Passed: Able to get expected value from slot 0!");
        }
        catch (Exception e)
        {
            Console.WriteLine("TEST FAILED: UNABLE TO GET FROM SLOT 0");
            Console.WriteLine(e.Message);
        }

        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Can get from slots 0-4?");
        testPassed = true;
        for (int i = 0; i < SMART_ARRAY_SIZE; i++)
        {
            try
            {
                valueGotten = sa.GetAtIndex(i);
                if (valueGotten != 10 * i)
                {
                    Console.WriteLine("TEST FAILED:  UNEXPECTED VALUE AT SLOT {0} (EXPECTED {1}, GOT {2})", i, i * 10, valueGotten);
                    testPassed = false;
                    break; // out of the loop
                }
                else
                    Console.WriteLine("Test Passed: Able to get expected value from slot 0!");
            }
            catch (Exception e)
            {
                Console.WriteLine("TEST FAILED: UNABLE TO GET FROM SLOT {0}", i);
                Console.WriteLine(e.Message);
                break;
            }
        }
        if (testPassed)
            Console.WriteLine("Test Passed: Able to get expected values!");
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to get from slot {0}?", SMART_ARRAY_SIZE);
        try
        {
            valueGotten = sa.GetAtIndex(SMART_ARRAY_SIZE);
            Console.WriteLine("TEST FAILED: GET FROM ELEMENT {0} DIDN'T OVERFLOW?", SMART_ARRAY_SIZE); 
        }
        catch (OverflowException e)
        {
            Console.WriteLine("Test Passed: Unable to get element at SMART_ARRAY_SIZE!");
        }
        catch (Exception e)
        {
            Console.WriteLine("TEST FAILED: GET ELEMENT AT SMART_ARRAY_SIZE FAILED, BUT FOR THE WRONG REASON");
            Console.WriteLine(e.Message);
        }
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to get from slot {0}?", SMART_ARRAY_SIZE + 10);
        try
        {
            valueGotten = sa.GetAtIndex(SMART_ARRAY_SIZE + 10);
            Console.WriteLine("TEST FAILED: GET FROM ELEMENT {0} DIDN'T OVERFLOW?", SMART_ARRAY_SIZE + 10);
        }
        catch (OverflowException e)
        {
            Console.WriteLine("Test Passed: Unable to get element at SMART_ARRAY_SIZE!");
        }
        catch (Exception e)
        {
            Console.WriteLine("TEST FAILED: GET ELEMENT AT SMART_ARRAY_SIZE FAILED, BUT FOR THE WRONG REASON");
            Console.WriteLine(e.Message);
        }
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to get from slot -1?");
        try
        {
            valueGotten = sa.GetAtIndex(-1);
            Console.WriteLine("TEST FAILED: GET FROM ELEMENT -1 DIDN'T UNDERFLOW");
        }
        catch (UnderflowException e)
        {
            Console.WriteLine("Test Passed: Unable to get element at -1!");
        }
        catch (Exception e)
        {
            Console.WriteLine("TEST FAILED: GET ELEMENT AT -1 FAILED, BUT FOR THE WRONG REASON");
            Console.WriteLine(e.Message);
        }
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to get from slot -10?");
        try
        {
            valueGotten = sa.GetAtIndex(-10);
            Console.WriteLine("TEST FAILED: GET FROM ELEMENT -10 DIDN'T UNDERFLOW");
        }
        catch (UnderflowException e)
        {
            Console.WriteLine("Test Passed: Unable to get element at -10!");
        }
        catch (Exception e)
        {
            Console.WriteLine("TEST FAILED: GET ELEMENT AT -10 FAILED, BUT FOR THE WRONG REASON");
            Console.WriteLine(e.Message);
        }
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("================= Find =================");
        Console.WriteLine("AutoChecked: Can find 0?");
        if (!sa.Find(0))
            Console.WriteLine("TEST FAILED: UNABLE TO FIND VALUE 0!");
        else
            Console.WriteLine("Test Passed: Able to find value 0!");
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Can find the values in slots 0-4?");
        testPassed = true;
        for (int i = 0; i < SMART_ARRAY_SIZE; i++)
        {
            try
            {
                valueGotten = sa.GetAtIndex(i);
                if (!sa.Find(valueGotten)) // test by getting from array
                {
                    Console.WriteLine("TEST FAILED: UNABLE TO FIND {0}!", valueGotten);
                    testPassed = false;
                    break; // out of the loop
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("TEST FAILED: FIND (iteration " + i + ") FAILED BECAUSE GETATINDEX FAILED");
            }
        }
        if (testPassed)
            Console.WriteLine("Test Passed: Able to find values that are already in the array!");
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Can find the values calculated to be in slots 0-4?");
        testPassed = true;
        for (int i = 0; i < SMART_ARRAY_SIZE; i++)
        {
            if (!sa.Find(i * 10)) // test by re-calculating the result
            {
                Console.WriteLine("TEST FAILED: UNABLE TO FIND {0}!", i * 10);
                testPassed = false;
                break; // out of the loop
            }
        }
        if (testPassed)
            Console.WriteLine("Test Passed: Able to find values calculated to be in the array!");
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to find -1?");
        if (sa.Find(-1))
            Console.WriteLine("TEST FAILED: ABLE TO FIND -1, WHICH SHOULD NOT BE PRESENT");
        else
            Console.WriteLine("Test Passed: Unable to find nonexistent value -1!");
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to find -10?");
        if (sa.Find(-10))
            Console.WriteLine("TEST FAILED: ABLE TO FIND -10, WHICH SHOULD NOT BE PRESENT");
        else
            Console.WriteLine("Test Passed: Unable to find nonexistent value -10!");
        Console.WriteLine("\n*******************\n");

        Console.WriteLine("AutoChecked: Should NOT be able to find 11?");
        if (sa.Find(11))
            Console.WriteLine("TEST FAILED: ABLE TO FIND 11, WHICH SHOULD NOT BE PRESENT");
        else
            Console.WriteLine("Test Passed: Unable to find nonexistent value 11!");
        Console.WriteLine("\n*******************\n");
    }
}

}

Upvotes: 0

Views: 932

Answers (4)

Peter B
Peter B

Reputation: 24137

In .NET, arrays will throw a System.IndexOutOfRangeException in both such cases, so that is what you need to check for:

try
{
    rgNums[idx]=val;
}
catch (System.IndexOutOfRangeException ex)
{
    Console.WriteLine(ex.Message);
}

There is no built-in exception for Underflow in the framework.

There is an OverflowException, but is used for when a value goes out of the allowed range for its type, e.g. an operation of type int that produces a value that exceeds Int32.MaxValue.

If your specification requires Under- and Overflow exceptions, then you will have to implement these yourself as custom Exception classes, and you will need to check for the specific range violations before they occur inside your SetAtIndex method and then throw each corresponding exception yourself. Example code:

public void SetAtIndex(int idx, int val)
{
    try
    {
        CheckIndex(rgNums, idx); /* NEW CODE */
        rgNums[idx] = val;
    }
    catch (UnderflowException Exception)
    {
        Console.WriteLine(Exception.Message);
    }
    catch (OverflowException Exception)
    {
        Console.WriteLine(Exception.Message);
    }
}

public int GetAtIndex(int idx)
{
    try
    {
        CheckIndex(rgNums, idx); /* NEW CODE */
        return rgNums[idx];
    }
    catch (UnderflowException Exception)
    {
        Console.WriteLine(Exception.Message);
    }
    catch (OverflowException Exception)
    {
        Console.WriteLine(Exception.Message);
    }

    return 0;
}

private void CheckIndex(int[] arr, int idx)
{
    if (idx < 0)
        throw new UnderflowException();
    if (idx >= arr.Length)
        throw new OverflowException();
}

combined with

public class UnderflowException : Exception
{
    // add what you need here, if anything...
}

public class OverflowException : Exception
{
    // add what you need here, if anything...
}

Working demo: https://dotnetfiddle.net/qJDYFt

Upvotes: 2

Dhiraj Kumar
Dhiraj Kumar

Reputation: 48

Overflow exceptions are used when any user has stored the maximum value of the datatypes and it increases from that values. As for example, int a=int.MaxValues ; a++ ; This will throw overflow exceptions. Underflow exceptions are just opposite to Overflow exceptions.

For throwing these exceptions , you have to configure below option in visual studio

  1. Right-click your Project within the Solution Explorer.
  2. Select Properties.
  3. Select the Build tab along the left.
  4. Select the Advanced… button.
  5. Within the Advanced Build Settings dialog, check the Check for arithmetic overflow /

underflow check-box.

public void OverFlowException() { try {

            // Overflow exception
            int maxNumber = int.MaxValue;
            maxNumber++;

        }
        catch (UnderflowException Exception)
        {

            Console.WriteLine(Exception.Message);
        }
        catch (OverflowException Exception)
        {
            Console.WriteLine(Exception.Message);
        }
    }

What you have used is different concept. In your code , if you want to throw UnderflowException , then just write below code public Exception UnderflowException: Exception { }

Hope this helps to resolve the query.

Upvotes: 0

Marco Salerno
Marco Salerno

Reputation: 5203

This is what you wanted to do:

class Program
{
    static void Main(string[] args)
    {
        var smartArray = new SmartArray(10);
        smartArray.SetAtIndex(100, 10);
    }
}

public class SmartArray
{
    private int[] _array;

    public SmartArray()
    {
        _array = new int[5];
    }

    public SmartArray(int length)
    {
        _array = new int[length];
    }

    public void SetAtIndex(int index, int value)
    {
        try
        {
            _array[index] = value;
        }
        catch (IndexOutOfRangeException ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }

    public int GetAtIndex(int index)
    {
        try
        {
            return _array[index];
        }
        catch (IndexOutOfRangeException ex)
        {
            Console.WriteLine(ex.ToString());
            return 0;
        }
    }
}

Anyway you should always handle errors instead of just ignoring them, you shouldn't catch the error in your class but handle it when you are using this object depending on the needs.

Upvotes: 0

Genotypek
Genotypek

Reputation: 213

You have to throw these exceptions manually before referencing the array. Just validate in try before array operation:

if (idx < 0)
    throw new UnderflowException();

if (idx >= rgNums.Count())
    throw new OverflowException();

Upvotes: 0

Related Questions