Skip to content

Commit

Permalink
update scripts
Browse files Browse the repository at this point in the history
* fixed version updates in release script
* formatted Python scripts with `black` - The uncompromising code formatter (https://black.readthedocs.io/)
* f-string all the things
  • Loading branch information
dalle committed Nov 23, 2024
1 parent 6801b0c commit b9793e1
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 193 deletions.
176 changes: 99 additions & 77 deletions script/amalgamate.py
Original file line number Diff line number Diff line change
@@ -1,100 +1,122 @@
# text parts
processed_files = { }
processed_files = {}

# authors
for filename in ['AUTHORS', 'CONTRIBUTORS']:
with open(filename, encoding='utf8') as f:
text = ''
for line in f:
if filename == 'AUTHORS':
text += '// fast_float by ' + line
if filename == 'CONTRIBUTORS':
text += '// with contributions from ' + line
processed_files[filename] = text + '//\n//\n'
for filename in ["AUTHORS", "CONTRIBUTORS"]:
with open(filename, encoding="utf8") as f:
text = ""
for line in f:
if filename == "AUTHORS":
text += "// fast_float by " + line
if filename == "CONTRIBUTORS":
text += "// with contributions from " + line
processed_files[filename] = text + "//\n//\n"

# licenses
for filename in ['LICENSE-MIT', 'LICENSE-APACHE', 'LICENSE-BOOST']:
lines = []
with open(filename, encoding='utf8') as f:
lines = f.readlines()
for filename in ["LICENSE-MIT", "LICENSE-APACHE", "LICENSE-BOOST"]:
lines = []
with open(filename, encoding="utf8") as f:
lines = f.readlines()

# Retrieve subset required for inclusion in source
if filename == 'LICENSE-APACHE':
lines = [
' Copyright 2021 The fast_float authors\n',
*lines[179:-1]
]
# Retrieve subset required for inclusion in source
if filename == "LICENSE-APACHE":
lines = [" Copyright 2021 The fast_float authors\n", *lines[179:-1]]

text = ''
for line in lines:
line = line.strip()
if len(line):
line = ' ' + line
text += '//' + line + '\n'
processed_files[filename] = text
text = ""
for line in lines:
line = line.strip()
if len(line):
line = " " + line
text += "//" + line + "\n"
processed_files[filename] = text

# code
for filename in [ 'constexpr_feature_detect.h', 'float_common.h', 'fast_float.h', 'ascii_number.h',
'fast_table.h', 'decimal_to_binary.h', 'bigint.h', 'digit_comparison.h', 'parse_number.h']:
with open('include/fast_float/' + filename, encoding='utf8') as f:
text = ''
for line in f:
if line.startswith('#include "'): continue
text += line
processed_files[filename] = '\n' + text
for filename in [
"constexpr_feature_detect.h",
"float_common.h",
"fast_float.h",
"ascii_number.h",
"fast_table.h",
"decimal_to_binary.h",
"bigint.h",
"digit_comparison.h",
"parse_number.h",
]:
with open("include/fast_float/" + filename, encoding="utf8") as f:
text = ""
for line in f:
if line.startswith('#include "'):
continue
text += line
processed_files[filename] = "\n" + text

# command line
import argparse

parser = argparse.ArgumentParser(description='Amalgamate fast_float.')
parser.add_argument('--license', default='TRIPLE', choices=['DUAL', 'TRIPLE', 'MIT', 'APACHE', 'BOOST'], help='choose license')
parser.add_argument('--output', default='', help='output file (stdout if none')
parser = argparse.ArgumentParser(description="Amalgamate fast_float.")
parser.add_argument(
"--license",
default="TRIPLE",
choices=["DUAL", "TRIPLE", "MIT", "APACHE", "BOOST"],
help="choose license",
)
parser.add_argument("--output", default="", help="output file (stdout if none")

args = parser.parse_args()


def license_content(license_arg):
result = []
if license_arg == 'TRIPLE':
result += [
'// Licensed under the Apache License, Version 2.0, or the\n',
'// MIT License or the Boost License. This file may not be copied,\n',
'// modified, or distributed except according to those terms.\n',
'//\n'
]
if license_arg == 'DUAL':
result += [
'// Licensed under the Apache License, Version 2.0, or the\n',
'// MIT License at your option. This file may not be copied,\n',
'// modified, or distributed except according to those terms.\n',
'//\n'
]
result = []
if license_arg == "TRIPLE":
result += [
"// Licensed under the Apache License, Version 2.0, or the\n",
"// MIT License or the Boost License. This file may not be copied,\n",
"// modified, or distributed except according to those terms.\n",
"//\n",
]
if license_arg == "DUAL":
result += [
"// Licensed under the Apache License, Version 2.0, or the\n",
"// MIT License at your option. This file may not be copied,\n",
"// modified, or distributed except according to those terms.\n",
"//\n",
]

if license_arg in ("DUAL", "TRIPLE", "MIT"):
result.append("// MIT License Notice\n//\n")
result.append(processed_files["LICENSE-MIT"])
result.append("//\n")
if license_arg in ("DUAL", "TRIPLE", "APACHE"):
result.append("// Apache License (Version 2.0) Notice\n//\n")
result.append(processed_files["LICENSE-APACHE"])
result.append("//\n")
if license_arg in ("TRIPLE", "BOOST"):
result.append("// BOOST License Notice\n//\n")
result.append(processed_files["LICENSE-BOOST"])
result.append("//\n")

if license_arg in ('DUAL', 'TRIPLE', 'MIT'):
result.append('// MIT License Notice\n//\n')
result.append(processed_files['LICENSE-MIT'])
result.append('//\n')
if license_arg in ('DUAL', 'TRIPLE', 'APACHE'):
result.append('// Apache License (Version 2.0) Notice\n//\n')
result.append(processed_files['LICENSE-APACHE'])
result.append('//\n')
if license_arg in ('TRIPLE', 'BOOST'):
result.append('// BOOST License Notice\n//\n')
result.append(processed_files['LICENSE-BOOST'])
result.append('//\n')
return result

return result

text = ''.join([
processed_files['AUTHORS'], processed_files['CONTRIBUTORS'],
*license_content(args.license),
processed_files['constexpr_feature_detect.h'],
processed_files['float_common.h'], processed_files['fast_float.h'],
processed_files['ascii_number.h'], processed_files['fast_table.h'],
processed_files['decimal_to_binary.h'], processed_files['bigint.h'],
processed_files['digit_comparison.h'], processed_files['parse_number.h']])
text = "".join(
[
processed_files["AUTHORS"],
processed_files["CONTRIBUTORS"],
*license_content(args.license),
processed_files["constexpr_feature_detect.h"],
processed_files["float_common.h"],
processed_files["fast_float.h"],
processed_files["ascii_number.h"],
processed_files["fast_table.h"],
processed_files["decimal_to_binary.h"],
processed_files["bigint.h"],
processed_files["digit_comparison.h"],
processed_files["parse_number.h"],
]
)

if args.output:
with open(args.output, 'wt', encoding='utf8') as f:
f.write(text)
with open(args.output, "wt", encoding="utf8") as f:
f.write(text)
else:
print(text)
print(text)
58 changes: 30 additions & 28 deletions script/analysis.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
import sys
from math import floor


def log2(x):
"""returns ceil(log2(x)))"""
y = 0
while((1<<y) < x):
y = y + 1
return y
"""returns ceil(log2(x)))"""
y = 0
while (1 << y) < x:
y = y + 1
return y


for q in range(1,17+1):
d = 5**q
for q in range(1, 17 + 1):
d = 5 ** q
b = 127 + log2(d)
t = 2** b
c = t//d + 1
assert c < 2**128
assert c >= 2**127
K = 2**127
if(not(c * K * d<=( K + 1) * t)):
print(q)
top = floor(t/(c * d - t))
sys.exit(-1)
t = 2 ** b
c = t // d + 1
assert c < 2 ** 128
assert c >= 2 ** 127
K = 2 ** 127
if not (c * K * d <= (K + 1) * t):
print(q)
top = floor(t / (c * d - t))
sys.exit(-1)

for q in range(18, 344+1):
d = 5**q
b = 64 + 2*log2(d)
t = 2**b
c = t//d + 1
assert c > 2**(64 +log2(d))
K = 2**64
if(not(c * K * d<=( K + 1) * t)):
print(q)
top = floor(t/(c * d - t))
sys.exit(-1)
for q in range(18, 344 + 1):
d = 5 ** q
b = 64 + 2 * log2(d)
t = 2 ** b
c = t // d + 1
assert c > 2 ** (64 + log2(d))
K = 2 ** 64
if not (c * K * d <= (K + 1) * t):
print(q)
top = floor(t / (c * d - t))
sys.exit(-1)

print("all good")
print("all good")
24 changes: 15 additions & 9 deletions script/mushtak_lemire.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,25 @@
# Appendix B of Number parsing at a gigabyte per second.
# Software: Practice and Experience 2021;51(8):1700–1727.
for q in range(-342, -27):
power5 = 5**-q
power5 = 5 ** -q
z = 0
while (1 << z) < power5:
z += 1
b = 2 * z + 2 * 64
c = 2**b // power5 + 1
c = 2 ** b // power5 + 1
while c >= (1 << 128):
c //= 2
all_tqs.append(c)
for q in range(-27, 0):
power5 = 5**-q
power5 = 5 ** -q
z = 0
while (1 << z) < power5:
z += 1
b = z + 127
c = 2**b // power5 + 1
c = 2 ** b // power5 + 1
all_tqs.append(c)
for q in range(0, 308 + 1):
power5 = 5**q
power5 = 5 ** q
while power5 < (1 << 127):
power5 *= 2
while power5 >= (1 << 128):
Expand All @@ -44,6 +44,7 @@ def continued_fraction(numer, denom):
numer, denom = denom, rem
return cf


# Given a continued fraction [a0; a1, a2, ..., an], returns
# all the convergents of that continued fraction
# as pairs of the form (numer, denom), where numer/denom is
Expand All @@ -58,17 +59,22 @@ def convergents(cf):
p_n = a_n * p_n_minus_1 + p_n_minus_2
q_n = a_n * q_n_minus_1 + q_n_minus_2
convergents.append((p_n, q_n))
p_n_minus_2, q_n_minus_2, p_n_minus_1, q_n_minus_1 = p_n_minus_1, q_n_minus_1, p_n, q_n
p_n_minus_2, q_n_minus_2, p_n_minus_1, q_n_minus_1 = (
p_n_minus_1,
q_n_minus_1,
p_n,
q_n,
)
return convergents


# Enumerate through all the convergents of T[q] / 2^137 with denominators < 2^64
found_solution = False
for j, tq in enumerate(all_tqs):
for _, w in convergents(continued_fraction(tq, 2**137)):
if w >= 2**64:
for _, w in convergents(continued_fraction(tq, 2 ** 137)):
if w >= 2 ** 64:
break
if (tq*w) % 2**137 > 2**137 - 2**64:
if (tq * w) % 2 ** 137 > 2 ** 137 - 2 ** 64:
print(f"SOLUTION: q={j-342} T[q]={tq} w={w}")
found_solution = True
if not found_solution:
Expand Down
Loading

0 comments on commit b9793e1

Please sign in to comment.