```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 is an int, base * 2**i is an int. Compare with cap (float).
            # If base is a float, base * 2**i involves float multiplication.
            
            # Let's handle both cases:
            if isinstance(base, int):
                # base * 2**i is an int
                power = 2 ** i
                product = base * power
                # Compare product (int) with cap (float)
                # If product > cap, use cap
                # But comparing int with float can cause issues if int is too large
                # However, Python handles int vs float comparison fine for reasonable values
                # The issue is when we try to convert a huge int to float
                # So we should avoid converting product to float
                # Instead, check if product > cap by comparing int with float
                # Python can compare int and float, but if int is too large, it might overflow
                # Actually, Python's int vs float comparison works correctly even for large ints
                # But the problem is when we do min(cap, base * 2**i) where base * 2**i is huge
                # min() with float and huge int might try to convert int to float
                
                # Better approach: check if base * 2**i > cap
                # If base * 2**i > cap, result is cap
                # Otherwise, result is base * 2**i (as float)
                
                # To avoid overflow, we can check:
                # If base * 2**i > cap, use cap
                # How to check without overflow?
                # If base == 0, handled above
                # If base > 0 and cap > 0:
                #   base * 2**i > cap iff 2**i > cap / base
                #   But cap / base might be problematic if base is very small
                
                # Alternative: use logarithms or check if 2**i is large enough
                # If i is large enough that 2**i > cap / base, then base * 2**i > cap
                
                # Let's compute threshold: if base * 2**i > cap
                # For large i, 2**i grows exponentially
                # We can check if 2**i > cap / base (when base > 0)
                # But cap / base as float might lose precision
                
                # Simpler: if base * 2**i as int > cap, use cap
                # Python can compare int > float correctly
                # The issue is min(cap, huge_int) tries to convert huge_int to float
                
                # So we should not use min() directly with huge int
                # Instead, check condition explicitly
                
                if product > cap:
                    value = cap
                else:
                    value = float(product)
            else:
                # base is a float
                # base * 2**i: 2**i is int, base is float
                # This multiplication converts 2**i to float, which can overflow
                # So we need to check if 2**i is too large
                # If base * 2**i > cap, use cap
                # Check: if 2**i > cap / base (when base > 0)
                if base == 0:
                    value = 0
                else:
                    # Check if 2**i > cap / base
                    # cap / base is a float
                    # 2**i as int, compare with float
                    # If 2**i > cap / base, then base * 2**i > cap
                    threshold = cap / base
                    if 2 ** i > threshold:
                        value = cap
                    else:
                        value = base * (2 ** i)
        result.append(value)
    return result
```