```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):
        # Avoid computing 2**i as a huge int that can't convert to float
        # Instead, compute base * 2**i carefully
        # If base == 0, then base * 2**i == 0 for all i
        if base == 0:
            value = 0.0
        else:
            # Compute base * 2**i without creating huge ints
            # We can use logarithms or iterative multiplication
            # But simpler: if 2**i is too large, the result will exceed cap
            # So we can check if base * 2**i > cap without computing the full value
            
            # Use math.log2 to check if base * 2**i > cap
            # base * 2**i > cap  <=>  2**i > cap / base  <=>  i > log2(cap / base)
            # But we need to handle edge cases
            
            # Alternative: iteratively compute, but stop early if value exceeds cap
            # Since we're building a list, we can compute incrementally
            
            # Let's use a different approach: compute value = base * 2**i
            # but avoid huge int by checking if i is large enough that base * 2**i > cap
            
            # If base > 0 and cap > 0:
            # base * 2**i > cap  <=>  2**i > cap / base
            # Take log2: i > log2(cap / base)
            # If i > log2(cap / base), then value = cap
            
            import math
            if cap == 0:
                value = 0.0
            else:
                # Check if base * 2**i > cap
                # If base == 0, handled above
                # If cap == 0, handled above
                # Otherwise, compute log2(cap / base)
                # But cap / base could be problematic if base is very small
                # Let's use a safe approach
                
                # Compute 2**i as float directly to avoid huge int
                # 2.0 ** i as float won't overflow for reasonable i
                # But for very large i, 2.0**i can overflow to inf
                # We need to handle that
                
                # If i is large, 2.0**i might be inf
                # But if base * 2.0**i > cap, we just use cap
                
                # Let's compute step by step
                # value = base * (2.0 ** i)
                # If 2.0 ** i overflows to inf, then base * inf = inf > cap, so value = cap
                
                try:
                    power = 2.0 ** i
                    value = base * power
                    if value > cap:
                        value = cap
                except OverflowError:
                    value = cap
            
            result.append(value)
            continue
        
        result.append(value)
    
    return result
```