Re:How many floating-point numbers are in the interval [0,1]...
by pansa2 on Saturday April 15, 2023 @10:55AM
(#35581173)
I did the same thing, recalling "There are Only Four Billion Floats–So Test Them All!" [0]. Except I used Python, so it took over 10 minutes:
[0] https://randomascii.wordpress.com/2014/01/27/theres-only-fou...
[ Parent
| on HN ]
Re:How many floating-point numbers are in the interval [0,1]...
by jherskovic on Saturday April 15, 2023 @01:39PM
(#35582726)
My very-slightly-different Python implementation runs in 9m56s minutes on Python 3.11, but in 2m54s using pypy3.9 (all on an M1 Max)
pypy never ceases to amaze me for low-effort performance gains on computational stuff.
A naive implementation in C compiled with Apple's clang (-O2) takes 0.62 seconds, of course.
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")