import micropython
from math import sin

# Versión simplificada que debería funcionar en Wokwi
@micropython.asm_thumb
def sin_taylor_scaled(r0):  # r0 = x * 100 (entero)
    # Inicialización
    mov(r1, r0)         # r1 = término actual = x
    mov(r2, r0)         # r2 = x original
    mov(r3, r1)         # r3 = resultado acumulado
    mov(r4, 1)          # r4 = signo (1 = positivo, 0 = negativo)
    mov(r5, 1)          # r5 = índice del término
    
    # Bucle principal
    label(loop)
    # Potencia: r6 = x^(2n+1)
    mov(r6, r2)         # r6 = x
    mul(r6, r2)         # x^2
    mul(r6, r2)         # x^3
    
    # Selección de factorial
    cmp(r5, 1)
    beq(fact3)
    cmp(r5, 2)
    beq(fact5)
    cmp(r5, 3)
    beq(fact7)
    b(endloop)
    
    label(fact3)
    mov(r7, 6)          # 3! = 6
    b(dividir)
    
    label(fact5)
    mov(r7, 120)        # 5! = 120 (simplificado)
    b(dividir)
    
    label(fact7)
    mov(r7, 5040)       # 7! = 5040 (simplificado para Wokwi)
    b(dividir)
    
    label(dividir)
    # División entera r6 / r7
    mov(r1, 0)          # resultado parcial
    
    label(divloop)
    cmp(r6, r7)
    blt(enddiv)
    sub(r6, r6, r7)
    add(r1, r1, 1)
    b(divloop)
    
    label(enddiv)
    # Aplicar signo
    cmp(r4, 0)
    beq(negativo)
    b(sumar)
    
    label(negativo)
    neg(r1, r1)
    
    label(sumar)
    add(r3, r3, r1)     # sumar el término al resultado
    
    # Cambiar signo (r4 ^= 1)
    mov(r6, 1)
    eor(r4, r6)
    
    # Siguiente término
    add(r5, r5, 1)
    cmp(r5, 4)          # 4 términos
    blt(loop)
    
    label(endloop)
    mov(r0, r3)         # devolver resultado

# Código principal de prueba
def test_sin():
    print("Calculando aproximación del seno usando Serie de Taylor")
    print("------------------------------------------------------")
    
    x = 0.1  # radianes
    x_scaled = int(x * 100)
    resultado = sin_taylor_scaled(x_scaled)
    valor_real = sin(x)
    
    print(f"sin({x}) aproximado ≈ {resultado / 100:.5f}")
    print(f"sin({x}) real = {valor_real:.5f}")
    print(f"Error absoluto: {abs(valor_real - resultado/100):.7f}")

# Ejecutar la prueba
test_sin()