Heart containing Coding Chica Java 101

Byte Adding – To Wrap or Not To Wrap?

TIP: References Quick List

Additional Info:

Is there an easy way to ensure that we don’t have the over/under flow wrapping errors we saw in the last post?

Yep. We are only adding 2 bytes, which together have:

  • Minimum value of -128 + -128 = -256
  • Maximum value of 127 + 127 = 254

The int value that Java wanted to return before we added explicit casting in the last post is well beyond the possible range of values we might return in our existing add method. Therefore, we can just remove the explicit casting we did in the last post and return the int value that Java wanted to return to get around the issue our original casting caused. Let’s do that in a test-driven-development approach.

Primitive TypeMinimum Value
(Inclusive)
Maximum Value
(Inclusive)
byte-128127
int-2^312^31 – 1

It was still good to have the casting for a short time, so we could see what Java does with over and under flow scenarios. Now, let’s get rid of that issue.

Unit Test Updates

Let’s add the scenarios from add_whenInvokedWithOverflow_thenReturnsIntegerWrapAroundValues and add_whenInvokedWithUnderflow_thenReturnsIntegerWrapAroundValues to instead sit in add_whenInvoked_thenReturnsExpectedResult method’s scenarios and correct the expected result.

@CsvSource({"1,2,3", "0,0,0", "-1,1,0", "127,1,128", "127,2,129", "-128,-1,-129", "-128,-2,-130"})

Then, we can delete the add_whenInvokedWithOverflow_thenReturnsIntegerWrapAroundValues and add_whenInvokedWithUnderflow_thenReturnsIntegerWrapAroundValues tests entirely.

Next, let’s change the expected result input parameter to be an int type:

void add_whenInvoked_thenReturnsExpectedResult(byte value1, byte value2, int expectedResult) {

Similarly, we need to update the actualResult’s type to int:

int actualResult = App.add(value1, value2);

Changing the Return Type

Let’s change the App.add method’s return type and the related Javadoc comment to reflect that it is now an int value:

/**
 * Add two byte values.
 *
 * @param byteValue1 The first value to add.
 * @param byteValue2 The second value to add.
 * @return An int value representing the two values added together.
 */
public static int add(byte byteValue1, byte byteValue2) {

Run Unit Tests for Failure

If we run the Maven build, we should now see failures for the newly moved scenarios:

[ERROR] Failures:
[ERROR]   AppTest$AddBytesTest.add_whenInvoked_thenReturnsExpectedResult:75 127+1=128 ==> expected: <128> but was: <-128>
[ERROR]   AppTest$AddBytesTest.add_whenInvoked_thenReturnsExpectedResult:75 127+2=129 ==> expected: <129> but was: <-127>
[ERROR]   AppTest$AddBytesTest.add_whenInvoked_thenReturnsExpectedResult:75 -128+-1=-129 ==> expected: <-129> but was: <127>
[ERROR]   AppTest$AddBytesTest.add_whenInvoked_thenReturnsExpectedResult:75 -128+-2=-130 ==> expected: <-130> but was: <126>

Add Logic Updates

Now, let’s change the logic of the App.add method to remove the casting:

public static int add(byte byteValue1, byte byteValue2) {
    return byteValue1 + byteValue2;
}

Maven Build for Success

Now, if we run the Maven build, we should see success.

Commit

Let’s commit our fix for the add’s over/underflow wrapping issues.

Byte Adding – To Wrap or Not To Wrap?

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.