UDT - can't redefine abs math function

New to FreeBASIC? Post your questions here.
Post Reply
GWBASICcoder
Posts: 21
Joined: Jul 29, 2022 12:43

UDT - can't redefine abs math function

Post by GWBASICcoder »

Hi,

I have a arbitrary precision complex number UDT, and would like to redefine the log and abs
functions among others. I am able to override the log function but not the abs. I see this error.
I don't

Code: Select all

error 4: Duplicated definition, found 'abs' in 'declare function abs () as cplx
I don't have any duplicated abs functions anywhere in the code.

Code: Select all

 
type cplx
....

  declare function log () as cplx
  declare function abs () as cplx
end type
Imortis
Moderator
Posts: 1924
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: UDT - can't redefine abs math function

Post by Imortis »

ABS is a FB command. Might also be an asm command.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: UDT - can't redefine abs math function

Post by fxm »

Undefine a variable or procedure name (by '#undef') before redefining it is not recommended because this can cause strange and unexpected results (only safe for a macro name or a symbol).

Maybe use 'modulus' instead of 'abs' ?
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: UDT - can't redefine abs math function

Post by D.J.Peters »

@fxm I allways #undef abs ... and replace it in my math include files without any problems ?

Joshy
GWBASICcoder
Posts: 21
Joined: Jul 29, 2022 12:43

Re: UDT - can't redefine abs math function

Post by GWBASICcoder »

Yes, I found ABS works as an operator, but the operator cannot be member of the UDT.

Code: Select all

    operator abs (A as cplx) as cplx
What is the difference between an "FB" and "non-FB" command?

From ABS documentation, I see

Dialect Differences:
In the -lang qb dialect, this operator cannot be overloaded.
Differences from QB:
None

However, I am not in the QB dialect.

Thanks
GWBASICcoder
Posts: 21
Joined: Jul 29, 2022 12:43

Re: UDT - can't redefine abs math function

Post by GWBASICcoder »

Yes, #undef abs works. Thanks.

Funnily, a new definition of abs as an operator does not work now (error 157: Expected operator, found 'abs' in 'operator abs ...'), but log works outside (not a member of UDT).

But, log only works as an operator, trying to define it as a function gives -- error 4: Duplicated definition, found 'log' in 'function log ...'

I ended up #undef-ing both and redefining as functions.
fxm wrote: Aug 20, 2022 20:42 Undefine a variable or procedure name (by '#undef') before redefining it is not recommended because this can cause strange and unexpected results (only safe for a macro name or a symbol).

Maybe use 'modulus' instead of 'abs' ?
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: UDT - can't redefine abs math function

Post by fxm »

As dodicat temporarily posted, for me too, the safest is to overload the unary operators 'log' and 'abs':

Code: Select all

type cplx
'....

end type

operator log (byref c as cplx) as cplx
  dim as cplx c0
'  ....
  return c0
end operator

operator abs (byref c as cplx) as cplx
  dim as cplx c0
'  ....
  return c0
end operator


dim as cplx c1
'.....
dim as cplx c2
c2 = abs(c1)
'.....
These operators thus defined can be used like functions.
The advantage of this method is that the builtin 'log' and 'abs' operators are still available for other data types than cplx.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: UDT - can't redefine abs math function

Post by fxm »

D.J.Peters wrote: Aug 21, 2022 2:35 @fxm I allways #undef abs ... and replace it in my math include files without any problems ?
Indeed, this seems to work fine:

Code: Select all

Type UDT
    Dim As Double d
    #undef Abs
    Declare Function abs() As UDT
End Type

Function UDT.abs() As UDT
    Dim As UDT u
    u.d = Sgn(This.d) * This.d
    Return u
End Function

Dim As UDT u1
u1.d = -3.14159
Print u1.d

Dim As UDT u2
u2 = u1.abs()
Print u2.d

Sleep
but .....

You must be sure that no FB keyword used in the user code internally calls the builtin keywords 'log' or 'abs'.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: UDT - can't redefine abs math function

Post by D.J.Peters »

my mistake I #undef abs,sin, etc. and replace them with functions not class members or operators :-)
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: UDT - can't redefine abs math function

Post by dodicat »

The basic math functions in fb are present in the c runtime, so you can undef any of them and re define them from crt.
Even one simple complex function, which just happens to be abs.
(The abs() of a complex number is a floating point number)

Code: Select all

#include "crt.bi"
Type UDT
    Dim As Double x,y
    #undef Abs
    Declare Function abs() As double
End Type

Function UDT.abs() As double
    Return _cabs(*cast(_complex ptr,@this))
End Function

function abs overload(x as double) as double
      return fabs(x)
end function

function abs(x as longint) as longint
return llabs(x)
end function

Dim As UDT u1
u1.x = -3.14159
Print u1.x

Dim As double u2
u2 = u1.abs()
Print u2

print type<UDT>(3,4).abs()

print abs(-9223372036854775807)
print abs(-9223372036854775807#)

Sleep 
GWBASICcoder
Posts: 21
Joined: Jul 29, 2022 12:43

Re: UDT - can't redefine abs math function

Post by GWBASICcoder »

Thanks for the replies.

One other inconsistency I found:

Neither +=, nor << are FreeBASIC or BASIC operators, but I can define += (and -=, *= etc.) as type
members, but trying to declare << as type member give:

Code: Select all

rror 153: Operator cannot be a member function (TODO), before '<' in 'declare operator << (A as cplx)
A << B is equivalent to A * 2^B
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: UDT - can't redefine abs math function

Post by fxm »

Only builtin operators can be overloaded with user defined types:
  • special operators (over-loadable as member):
    • 'cast', '@', '[]', 'new', 'delete', 'for', 'step', 'next'
  • assignment operators (over-loadable as member):
    • 'let', '+=', '-=', '*=', '&=', '/=', '\=', 'mod=', 'shl=', 'shr=', 'and=', 'or=', 'xor=', 'imp=', 'eqv=', '^='
  • unary operators (over-loadable as non member):
    • '-', 'not', '*', '->', 'abs', 'sgn', 'fix', 'frac', 'int', 'exp', 'log', 'sin', 'asin', 'cos', 'acos'', 'tan', 'atn', 'len', 'sqr'
  • binary operators (over-loadable as non member):
    • '+', '-', '*', '&', '/', '\', 'mod', 'shl', 'shr', 'and', 'or', 'xor', 'imp', 'eqv', '^', '=', '<>', '<', '>', '<=', '>='
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: UDT - can't redefine abs math function

Post by dodicat »

For complex numbers the 4 main operators +, -, *, / are usually set up to begin with.
Then the method operators +=, -=, *=, /= are not needed.

Code: Select all


type complex
 as double re,im
end type


Operator +(n1 As complex,n2 As complex) As complex
Return Type<complex>(n1.re+n2.re,n1.im+n2.im)'n
End Operator

Operator -(n1 As complex,n2 As complex) As complex
Return Type<complex>(n1.re-n2.re,n1.im-n2.im)
End Operator

Operator *(n1 As complex,n2 As complex) As complex
Return Type<complex>(n1.re*n2.re - n1.im*n2.im,n1.im*n2.re + n1.re*n2.im)'n
End Operator

Operator /(n1 As complex,n2 As complex) As complex
Dim As Double d = n2.re*n2.re+n2.im*n2.im
Return Type<complex>((n1.re*n2.re+n1.im*n2.im)/d,(n1.im*n2.re - n1.re*n2.im)/d)
End Operator


dim as complex z1=type(1,-1),z2=type(5,6)

dim as complex t=z1

print t.re,t.im
t+=z2
print t.re,t.im

t=z1
t-=z2
print t.re,t.im

t=z1
t*=z2
print t.re,t.im

t=z1
t/=z2
print t.re,t.im


t*=z2
print t.re,t.im
sleep

 
Post Reply