News for hackers. Stuff that matters.
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")

There are no comments on this comment yet.