### Exercise to understand double.

Many developers fell like double' rounding and representation errors and random errors which are wild and uncontrollable.   This exercise is intended to help understand what double is really doing.

Write a method to convert double into text in a direct ByteBuffer which starts

public static void append(ByteBuffer bb, double d) {
long val = Double.doubleToRawLongBits(d);
int sign = (int) (val >>> 63);
int exp = (int) ((val >>> 52) & 2047);
long mantissa = val & ((1L << 52) - 1);

The goal is to write +/- 0.0001 to 100000.0 using no objects or double, just integer arithmetic.  Values outside this range can use BigDecimal or Double as a fall back.

• Implement this to convert to text the actual representation of the double, just as new BigDecimal(double) does. (Write a test which compares the values) e.g. 0.1d prints as 0.1000000000000000055511151231257827021181583404541015625
• Implement this to convert to text the closest rounded value which would have this representation as a double. i.e. 0.1d prints as 0.1
• In both cases, compare the performance with using BigDecimal and Double.toString copied to a ByteBuffer.
• Determine what is the actual range you need to use BigDecimal or Double as a fall back. Note: there is no strictly correct answer to this.
Bonus Points: Write the routine to use Unsafe and compare the performance.