Re:How many floating-point numbers are in the interval [0,1]...
by eesmith on Saturday April 15, 2023 @04:26PM
(#35584224)
This should be a bit faster, while still sticking to stock Python:
import time, array
n = 0
start_time = time.time()
values = bytearray(b"".join(i.to_bytes(4, "big") for i in range(2**24)))
for prefix in range(256):
values[::4] = prefix.to_bytes(1, "big") * (2**24)
arr = array.array("f", values)
n += sum(1 for x in arr if 0.0 <= x <= 1.0)
print(f"Found: {n} Time: {time.time() - start_time:.1f} seconds")
It uses an array.array() to convert from a large number of concatenated 4 bytes to floats, rather than going through the struct module one-by-one.
Rather than build all 0x1_0000_0000 values in memory, I process 0x100_0000 at a time, and accumulate the partial sums.
On my laptop this reports "Found: 1065353218 Time: 228.5 seconds", so just under 4 minutes.
A slightly improved algorithm in NumPy takes 5.4 seconds.
import time, numpy as np
start_time = time.time()
arr = np.arange(2**24, dtype=np.uint32)
incr = np.full(2**24, 2**24, dtype=arr.dtype)
values = np.frombuffer(arr, np.float32)
n = ((0.0 < values) & (values <= 1.0)).sum()
for i in range(1, 256):
arr += incr
n += ((0.0 < values) & (values <= 1.0)).sum()
print(f"Found: {n} Time: {time.time() - start_time:.1f} seconds")
Rather than build all 0x1_0000_0000 values in memory, I process 0x100_0000 at a time, and accumulate the partial sums.
On my laptop this reports "Found: 1065353218 Time: 228.5 seconds", so just under 4 minutes.
A slightly improved algorithm in NumPy takes 5.4 seconds.