```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 converting huge int to float
        # If base is 0, delay is 0
        if base == 0:
            delay = 0.0
        else:
            # Check if base * 2**i exceeds cap
            # We can compare using integer arithmetic when possible
            # base * 2**i > cap  <=>  2**i > cap / base
            # But cap/base may not be integer. Use float comparison carefully.
            # Alternative: compute 2**i as int, then multiply by base (float).
            # The issue is 2**i becomes huge int, and base * huge_int converts to float -> overflow.
            # So we need to avoid creating huge int.
            # Instead, check if 2**i > cap / base (using float division).
            # If cap / base is small, then for large i, 2**i will exceed it.
            # We can compute threshold = cap / base (float).
            # Then for each i, if 2**i > threshold, delay = cap.
            # But 2**i as int can be huge. We can compare using logarithms or iterative doubling.
            # Simpler: track current power as float, but start from 1.0 and double each time.
            # This avoids huge int conversion.
            pass
        
        # Better approach: use float power tracking
        # Start with power = 1.0, multiply by 2 each iteration
        # This avoids huge int -> float conversion overflow.
        # But we need to recompute for each i independently? No, we can track incrementally.
        # However, the function is called once, so we can track incrementally.
        # Let's restructure:
        pass
    
    # Rewrite with incremental float power
    result = []
    power = 1.0
    for i in range(attempts):
        delay = min(cap, base * power)
        result.append(delay)
        power *= 2.0
    return result
```