```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, result is 0
        if base == 0:
            value = 0
        else:
            # Check if base * 2**i exceeds cap
            # We need to compare base * 2**i with cap
            # Since cap is a float, we need to handle carefully
            # If 2**i is too large, base * 2**i will definitely exceed cap (if cap is finite)
            # But we need to avoid OverflowError when converting int to float
            
            # Approach: if base * 2**i > cap, use cap
            # To check this without overflow:
            # If base == 0, handled above
            # If cap == 0, value = 0
            if cap == 0:
                value = 0
            else:
                # Check if base * 2**i > cap
                # We can do: if base * 2**i > cap, use cap
                # But base * 2**i might be huge int, and cap is float
                # Compare: base * 2**i > cap
                # If base * 2**i is an int and cap is a float, Python can compare int and float
                # But if the int is too large to convert to float, it raises OverflowError
                
                # Strategy: if 2**i is so large that base * 2**i > cap, we can detect this
                # by checking if base * 2**i > cap using integer arithmetic when possible
                # Or: if base * 2**i would overflow float, it's definitely > cap (assuming cap is finite)
                
                # Let's compute power = 2**i as int
                power = 2 ** i
                product = base * power  # base is float, power is int -> this converts power to float, may overflow
                
                # To avoid overflow, check if product would exceed cap
                # If base > 0 and cap > 0:
                # base * 2**i > cap  <=>  2**i > cap / base
                # We can check if 2**i > cap / base without computing 2**i as float
                
                # But cap / base is a float. If cap / base is very large, 2**i might be larger.
                # Alternative: if base * 2**i > cap, use cap.
                # We can check: if base * 2**i > cap, but avoid overflow.
                
                # If base is 0, handled. If cap is 0, handled.
                # If base > 0 and cap > 0:
                # Check if 2**i > cap / base
                # cap / base is a float. If cap / base is inf, then 2**i is always <= cap/base? No.
                # Let's think differently.
                
                # If base * 2**i > cap, we want cap.
                # If base * 2**i <= cap, we want base * 2**i.
                
                # To avoid overflow when computing base * 2**i:
                # If 2**i is too large to convert to float, then base * 2**i > cap (since cap is finite float).
                # So we can check: if 2**i > some threshold, use cap.
                
                # The maximum float is about 1.8e308. If base * 2**i > max_float, it overflows.
                # But we only care about comparing with cap.
                
                # Simpler approach: if base * 2**i > cap, use cap.
                # We can check this by: if base * 2**i > cap, but compute safely.
                
                # If base == 0: value = 0
                # If cap == 0: value = 0
                # Otherwise, base > 0 and cap > 0.
                
                # Check if base * 2**i > cap
