Skip to content

Instantly share code, notes, and snippets.

@michaeljclark
Last active November 20, 2022 20:53
Show Gist options
  • Save michaeljclark/28dc095e0f0385e8eb2568349071712e to your computer and use it in GitHub Desktop.
Save michaeljclark/28dc095e0f0385e8eb2568349071712e to your computer and use it in GitHub Desktop.
phydate128 — a 128-bit date format with 4-bit prefix and 124-bit counter
#!/usr/bin/env python3
# phydate128 — a 128-bit variable width datetime format
#
# struct { int<4> timebase; uint<4> length; bytes<length> counter; }
#
# prefix byte is composed of a 4-bit signed frequency base and 4-bit length
# frequency base is signed two's complement where 0b0000 is femtoseconds
# length indicates the size of the variable length counter field in bytes.
#
# 4-bit frequency base in units of one thousand (10^(30-(3*(5+base))))
# 4-bit length of counter in bytes
# 120-bit two's complement signed integer count relative to January 1st 2000
import math
si_units = [
( 'nonillian', 'quetta','Q', 30, None ),
( 'octillian', 'ronna', 'R', 27, None ),
( 'septillian', 'yotta', 'Y', 24, None ),
( 'sextillian', 'zetta', 'Z', 21, None ),
( 'quintillion', 'exa', 'E', 18, None ),
( 'quadrillion', 'peta', 'P', 15, None ),
( 'trillion', 'tera', 'T', 12, None ),
( 'billion', 'giga', 'G', 9, None ),
( 'million', 'mega', 'M', 6, None ),
( 'thousand', 'kilo', 'K', 3, None ),
( '', '', '', 0, 5 ),
( 'thousandth', 'milli', 'm', -3, 4 ),
( 'millionth', 'micro', 'µ', -6, 3 ),
( 'billionth', 'nano', 'n', -9, 2 ),
( 'trillionth', 'pico', 'p', -12, 1 ),
( 'quadrillionth', 'femto', 'f', -15, 0 ),
( 'quintillionth', 'atto', 'a', -18, -1 ),
( 'sextillionth', 'zepto', 'z', -21, -2 ),
( 'septillionth', 'yocto', 'y', -24, -3 ),
( 'octillionth', 'ronto', 'r', -27, -4 ),
( 'nonillionth', 'quecto','q', -30, -5 ),
]
def format_range(years):
yr_symbol = ''
yr_count = 0
yr_max = 0
for unit in si_units:
frac_name, si_name, si_symbol, exponent, code = unit;
denom = math.pow(10,exponent)
d_years = years / denom
if d_years > 1 and (d_years < yr_max or yr_max == 0):
yr_denom = denom
yr_symbol = frac_name
yr_count = int(d_years)
yr_max = yr_count
if len(yr_symbol) == 0:
return "~{} years".format(yr_count)
elif yr_denom < 1:
return "~{} {}s year".format(yr_count, yr_symbol)
else:
return "~{} {} years".format(yr_count, yr_symbol)
def format_freq(code):
sym = ''
exp = (30-(3*(code+5)))
for unit in si_units:
frac_name, si_name, si_symbol, exponent, code = unit;
if exponent == exp:
sym = si_symbol
return "1{}Hz".format(sym)
def format_code(code):
return format(code if code >= 0 else 16+code, '04b')
print("""
phydate128 — a 128-bit variable width datetime format
prefix byte is composed of a 4-bit signed frequency base and 4-bit length
frequency base is signed two's complement where 0b0000 is femtoseconds
length indicates the size of the variable length counter field in bytes.
%14s %5s %5s %5s %5s %5s %5s %25s
%14s %5s %5s %5s %5s %5s %5s %25s"""
% (
'unit', 'suff', 'freq', 'base', 'bit/S',
'bit/Y', 'Ybits', 'range',
'--------------', '-----', '-----', '-----', '-----',
'-----', '-----', '-------------------------') )
for unit in si_units:
frac_name, si_name, si_symbol, exponent, code = unit;
if code is not None:
sec_cycles = math.pow(10, -exponent)
year_cycles = float(365 * 86400) * sec_cycles
bits_psec = int(math.ceil(math.log2(sec_cycles)))
bits_pyear = int(math.ceil(math.log2(year_cycles))) + 5 # sign bit
year_bits = 124 - bits_pyear
years = math.pow(2, year_bits)
print("%14s %5s %5s %5s %5s %5s %5s %25s" %
(si_name + 'seconds', si_symbol + 's', format_freq(code),
format_code(code), bits_psec, bits_pyear, year_bits, format_range(years)))
print()
phydate128 — a 128-bit variable width datetime format
prefix byte is composed of a 4-bit signed frequency base and 4-bit length
frequency base is signed two's complement where 0b0000 is femtoseconds
length indicates the size of the variable length counter field in bytes.
unit suff freq base bit/S bit/Y Ybits range
-------------- ----- ----- ----- ----- ----- ----- -------------------------
seconds s 1Hz 0101 0 30 94 ~19 octillian years
milliseconds ms 1KHz 0100 10 40 84 ~19 septillian years
microseconds µs 1MHz 0011 20 50 74 ~18 sextillian years
nanoseconds ns 1GHz 0010 30 60 64 ~18 quintillion years
picoseconds ps 1THz 0001 40 70 54 ~18 quadrillion years
femtoseconds fs 1PHz 0000 50 80 44 ~17 trillion years
attoseconds as 1EHz 1111 60 90 34 ~17 billion years
zeptoseconds zs 1ZHz 1110 70 100 24 ~16 million years
yoctoseconds ys 1YHz 1101 80 110 14 ~16 thousand years
rontoseconds rs 1RHz 1100 90 120 4 ~16 years
quectoseconds qs 1QHz 1011 100 130 -6 ~15 thousandths year
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment