```python
def retry_delays(attempts, base, cap):
    if isinstance(attempts, bool) or not isinstance(attempts, int):
        raise TypeError("attempts must be a non-negative integer")
    if attempts < 0:
        raise ValueError("attempts must be non-negative")
    if base < 0:
        raise ValueError("base must be non-negative")
    if cap < 0:
        raise ValueError("cap must be non-negative")
    
    result = []
    for i in range(attempts):
        # Compute base * 2**i without causing overflow by checking if 2**i would exceed cap/base
        # If base == 0, then base * 2**i == 0, so min(cap, 0) = 0
        if base == 0:
            result.append(0.0)
            continue
        
        # Check if 2**i * base > cap, i.e., 2**i > cap / base
        # To avoid computing huge 2**i, we can check if i is large enough that 2**i * base > cap
        # Since cap and base are non-negative, if cap == 0, then min(cap, ...) = 0
        if cap == 0:
            result.append(0.0)
            continue
        
        # We need min(cap, base * 2**i)
        # If base * 2**i >= cap, then result is cap
        # Otherwise, result is base * 2**i
        
        # To avoid overflow, check if 2**i * base > cap
        # This is equivalent to 2**i > cap / base
        # We can compute this safely by checking if i is large enough
        
        # If base * 2**i would overflow, we know it's > cap (since cap is finite), so result = cap
        # But we need to be careful: if base * 2**i <= cap, we compute it normally
        
        # Check if 2**i * base > cap
        # If i is large, 2**i can be huge. We can check: if i > some threshold, then 2**i * base > cap
        # Specifically, if 2**i > cap / base, then result = cap
        
        # Compute cap / base safely
        threshold = cap / base
        
        # If 2**i > threshold, result = cap
        # Otherwise, result = base * 2**i
        
        # To check if 2**i > threshold without computing 2**i for large i:
        # If i >= 1024, 2**i is astronomically large, definitely > threshold (since threshold is finite)
        # But we need to be precise. Let's check if i is large enough that 2**i > threshold.
        
        # For small i, compute directly. For large i, check if 2**i > threshold.
        # We can use logarithms or just check if i is large enough.
        
        # Simple approach: if i is large enough that 2**i * base > cap, return cap
        # We can check: if i > 1000, then 2**i is huge, so result = cap (assuming base > 0 and cap > 0)
        # But we need to be exact. Let's compute 2**i only when it won't overflow.
        
        # Python's int can handle large numbers, but converting to float can overflow.
        # So we need to avoid converting huge ints to float.
        
        # Strategy: if base * 2**i > cap, return cap. Otherwise, compute base * 2**i as float.
        # To check if base * 2**i > cap without overflow:
        # If i is large, 2**i is huge. We can check if 2**i > cap / base.
        # cap / base is a float. If i is large enough that 2**i > cap / base, return cap.
        
        # How large can i be before 2**i > cap / base?
        # If cap / base is, say, 8, then 2**3 = 8, so for i >= 3, 2**i >= 8, so base * 2**i >= cap.
        # We can compute log2(cap / base) to find the threshold.
        
        import math
        if base == 0:
            result.append(0.0)
            continue
        
        # Compute log2(cap / base)
        # If cap / base <= 0, but cap > 0 and base > 0, so cap / base > 0
        log2_threshold = math.log2(cap / base)
        
        # If i > log2_threshold, then 2**i > cap / base, so base * 2**i > cap, result = cap
        # If i <= log2_threshold, compute base * 2**i as float
        
        if i > log2_threshold:
            result.append(cap)
        else:
            result.append(base * (2 ** i))
    
    return result
```