RosettaCodeData/Task/Elliptic-curve-arithmetic/FreeBASIC/elliptic-curve-arithmetic.basic
2025-06-11 20:16:52 -04:00

98 lines
2.5 KiB
Text

Const As Double INF = 1e30
Type Punto
As Double x, y
Declare Constructor (x As Double = INF, y As Double = INF)
Declare Function copy() As Punto
Declare Function isZero() As Integer
Declare Function neg() As Punto
Declare Function dbl() As Punto
Declare Function sum(q As Punto) As Punto
Declare Function mul(n As Integer) As Punto
Declare Function ToString() As String
End Type
Dim Shared As Integer bCoeff = 7 ' Coeficiente de la curva elíptica
Constructor Punto(x As Double, y As Double)
This.x = Iif(Abs(x) > 1e20, INF, x)
This.y = Iif(Abs(y) > 1e20, INF, y)
End Constructor
Function Punto.copy() As Punto
Return Type(This.x, This.y)
End Function
Function Punto.isZero() As Integer
Return This.x >= 1e20 Or This.x <= -1e20 Or This.x = INF
End Function
Function Punto.neg() As Punto
Return Type(This.x, -This.y)
End Function
Function Punto.dbl() As Punto
If This.isZero() Then Return This.copy()
If Abs(This.y) < 1e-15 Then Return Punto()
Dim As Double L = (3 * This.x * This.x) / (2 * This.y)
Dim As Double x3 = L * L - 2 * This.x
Return Type(x3, L * (This.x - x3) - This.y)
End Function
Function Punto.sum(q As Punto) As Punto
If This.x = q.x And This.y = q.y Then Return This.dbl()
If This.isZero() Then Return q.copy()
If q.isZero() Then Return This.copy()
If Abs(q.x - This.x) < 1e-15 Then Return Punto()
Dim As Double L = (q.y - This.y) / (q.x - This.x)
Dim As Double x3 = L * L - This.x - q.x
Return Type(x3, L * (This.x - x3) - This.y)
End Function
Function Punto.mul(n As Integer) As Punto
Dim As Punto r = Punto(), p = This.copy()
While n > 0
If (n And 1) Then r = r.sum(p)
p = p.dbl()
n = n Shr 1
Wend
Return r
End Function
Function Punto.ToString() As String
If This.isZero() Then Return "Zero"
Return "(" & Str(Int(This.x * 1000) / 1000) & ", " & Str(Int(This.y * 1000) / 1000) & ")"
End Function
Sub show(s As String, p As Punto)
Print s & " " & p.ToString()
End Sub
Function from_y(y As Double) As Punto
Dim As Double n = y * y - bCoeff
Dim As Double x = Sgn(n) * Abs(n)^(1.0/3.0)
Return Type(x, y)
End Function
' Demonstrate
Dim As Punto a = from_y(1)
Dim As Punto b = from_y(2)
show("a =", a)
show("b =", b)
Dim As Punto c = a.sum(b)
show("c = a + b =", c)
Dim As Punto d = c.neg()
show("d = -c =", d)
show("c + d =", c.sum(d))
show("a + b + d =", a.sum(b.sum(d)))
show("a * 12345 =", a.mul(12345))
Sleep