import math


def format_file_size(size, unit='', precision=0):
    """Take a size in bits or bytes and return it all prettied
    up and rounded to whichever unit gives the smallest number.

    A fixed unit can be specified. Possible units are B, KiB,
    MiB, GiB, TiB, and PiB so far. Case-insensitive.

    Works on both negative and positive numbers. In the event
    that the given value is in bits, the user will have to
    use result = result[:-1] + 'b' to make it appear correct.

    Will calculate using integers unless precision is != 0.
    Will display using integers unless precision is > 0.
    """
    # Each unit's position in the list is crucial.
    # units[2] = 'MiB' and size / 1024**2 = size in MiB
    # units[3] = 'GiB' and size / 1024**3 = size in GiB
    units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']
    increment = 1024.0  # Must be float in Python 2.x to avoid floor division

    # Did the calling function specify a valid unit of measurement?
    if unit and unit.upper() in [x.upper() for x in units]:
        unit_idx = units.index(unit)
    else:
        unit_idx = min(int(math.log(abs(size), increment)), len(units) - 1)

    size /= increment ** unit_idx

    return '%.*f%s' % (precision, size, units[unit_idx])