```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 exceeds 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 overflow, 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 to compute 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 > cap / base
        # cap / base could be a float, but we can use integer comparison carefully
        
        # If i is large, 2**i can be huge. We can check if i >= some threshold.
        # Specifically, if 2**i * base > cap, then min is cap.
        # 2**i > cap / base
        # Since base > 0 and cap >= 0, cap / base is well-defined.
        
        # Use logarithm-free approach: if i is large enough that 2**i * base > cap, use cap.
        # We can compute this by checking if i >= log2(cap / base), but that uses math.log2 which is fine.
        # However, to avoid importing math, we can do iterative doubling or use bit_length.
        
        # Alternative: compute 2**i as an integer, but if it's too large, we know the result is cap.
        # We can check if i is large enough that 2**i * base > cap.
        # Since base and cap are floats, we need to be careful.
        
        # Let's use a safe approach: if i is large, 2**i can overflow when converted to float.
        # But we can check if 2**i * base > cap without computing 2**i as float.
        
        # If base * 2**i > cap, then result = cap.
        # This is equivalent to 2**i > cap / base.
        # cap / base is a float. If cap / base is very large, 2**i might overflow.
        
        # We can check if i is large enough that 2**i > cap / base.
        # Since cap / base is a float, we can compute it safely.
        # Then check if 2**i > cap / base.
        # But 2**i as an integer can be huge. We can check if i >= log2(cap / base).
        
        # To avoid math import, we can use bit_length or iterative check.
        # Let's compute cap / base as a float. If cap / base is inf, then 2**i * base > cap for all i, so result = cap.
        # If cap / base is finite, we can check if 2**i > cap / base.
        
        ratio = cap / base
        if ratio == float('inf'):
            result.append(cap)
            continue
        
        # Check if 2**i > ratio
        # If i is large, 2**i can be huge. We can check if i >= log2(ratio).
        # Without math, we can use bit_length of an integer approximation.
        
        # If ratio <= 1, then for i >= 1, 2**i >= 2 > ratio, so result = cap.
        # For i = 0, 2**0 = 1, so base * 1 = base, min(cap, base) = min(cap, base).
        
        # Let's handle i = 0 separately.
        if i == 0:
            result.append(min(cap, base))
            continue
        
        # For i >= 1, check if 2**i > ratio.
        # If ratio < 2, then for i >= 1, 2**i >= 2 > ratio, so result = cap.
        if ratio < 2:
            result.append(cap)
            continue
        
        # Now ratio >= 2. We need to check if 2**i > ratio.
        # 2**i as an integer. If i is large, 2**i can be huge.
        # We can check if i >= log2(ratio).
        # Without math, we can use bit_length.
        
        # Convert ratio to an integer approximation for comparison.
        # If ratio is a float, we can check if 2**i > ratio by comparing bit lengths.
        
        # If i is large enough that 2**i > ratio, result = cap.
        # We can check if i >= ratio.bit_length() if ratio were an integer.
        # But ratio is a float.
        
        # Let's use a different approach: compute 2**i as an integer, but if it's too large, we know the result is cap.
        # We can check if i is large enough that 2**i * base > cap.
        # Since base and cap are floats, we can do:
        # if i >= 1024, 2**i is huge, so 2**i * base > cap for any reasonable cap.
        # But this is not robust.
        
        # Better: use logarithm-free check.
        # 2**i > ratio
        # Take log2: i > log2(ratio)
        # Without math, we can approximate log2(ratio) using bit_length.
        
        # If ratio is a float, we can convert it to an integer for bit_length comparison.
        # But ratio might not be an integer.
        
        # Let's use a safe approach: if i is large, 2**i can overflow when converted to float.
        # But we can check if 2**i * base > cap without computing 2**i as float.
        
        # If base * 2**i > cap, then result = cap.
        # This is equivalent to 2**i > cap / base.
        # cap / base is a float. If cap / base is very large, 2**i might overflow.
        
        # We can check if i is large enough that 2**i > cap / base.
        # Since cap / base is a float, we can compute it safely.
        # Then check if 2**i > cap / base.
        # But 2**i as an integer can be huge. We can check if i >= log2(cap / base).
        
        # To avoid math import, we can use bit_length or iterative check.
        # Let's compute cap / base as a float. If cap / base is inf, then 2**i * base > cap for all i, so result = cap.
        # If cap / base is finite, we can check if 2**i > cap / base.
        
        # Use bit_length approach:
        # If ratio is a float, we can check if 2**i > ratio by comparing bit lengths.
        # If ratio < 2**i, then result = cap.
        
        # Let's compute 2**i as an integer. If it's too large, we know the result is cap.
        # We can check if i is large enough that 2**i > ratio.
        
        # If i >= 1024, 2**i is huge, so 2**i * base > cap for any reasonable cap.
        # But this is not robust.
        
        # Better: use logarithm-free check.
        # 2**i > ratio
        # Take log2: i > log2(ratio)
        # Without math, we can approximate log2(ratio) using bit_length.
        
        # If ratio is a float, we can convert it to an integer for bit_length comparison.
        # But ratio might not be an integer.
        
        # Let's use a different approach: compute 2**i as an integer, but if it's too large, we know the result is cap.
        # We can check if i is large enough that 2**i * base > cap.
        # Since base and cap are floats, we can do:
        # if i >= 1024, 2**i is huge, so 2**