Thursday, August 18, 2011

Java puzzler - Letter went missing

Recently I've implemented function that takes String and populates long so that it contains character values from the back of the string. However my unit test is failing because one Letter is missing. Are you able to put it to the right place so that unit tests will not fail without debugging the code?

import static org.junit.Assert.*;
import org.junit.Test;

public class StringToolsTest {

	static final char [] data = {0xca, 0xfe, 0xeb, 0xab, 0xee};
	static final String string5 = String.valueOf(data);
	static final String string0 = "";
	static final String string1 = "a";
	static final String string9 = "987654321";
	
	@Test
	public void testFillBackwards() {
		long l = 0;
		assertEquals(0xcafeebabeeL, StringTools.fillBackwards(string5, l));
		assertEquals(0L, StringTools.fillBackwards(string0, l));
		assertEquals(0x61L, StringTools.fillBackwards(string1, l));
		assertEquals(0x3837363534333231L, StringTools.fillBackwards(string9, l));
	}
}

public class StringTools {
	public static long fillBackwards(String s, long d)
	{
		long result = 0L;
		byte[] bytes = s.getBytes();
		for (int i=0; i<Math.min(8,bytes.length); i++){
			result |= ((bytes[bytes.length-i-1] & 0xff) << (8*i));
		}
		return result;
	}
}

Solution bellow (highlight to show):
The problem is on the line 29 in "& 0xFF". I should be doing &0xFFL instead. Why ? bytes[x]&0xff is by default int (both operands are widened to int), but then << is applied, result of which is type of left operand (java spec) and this is |= to long result. Solution is to make & operator to work on long values by adding L to 0xFF.
Puzzler on snipplr.

No comments: