Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

absolute value of difference

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR
View previous topic :: View next topic  
Author Message
Arera

Bascom Member



Joined: 23 Sep 2007
Posts: 386
Location: Wuppertal, Germany

germany.gif
PostPosted: Tue Jul 02, 2019 9:12 am    Post subject: absolute value of difference Reply with quote

Hi all,

working with unsigned vars, calculating the absolute value of the difference between to vars afforts a couple of steps.

Example using byte-constants:

89-5 = 84 'OK

5-89 = 171 'not the wanted result

So what I do is to take care to always substract the lower value from the higher one.

Pseudocode:

if a > b then
result = a - b
else
result = b - a
end if

My question:
Is there a more elegant way tho achieve the same?





(BASCOM-AVR version : 2.0.8.1 )
Back to top
View user's profile
Duval JP

Bascom Member



Joined: 22 Jun 2004
Posts: 1161
Location: France

france.gif
PostPosted: Tue Jul 02, 2019 10:43 am    Post subject: Reply with quote

I test
Code:

Dim J As Byte
Dim K As Byte
J = 89 - 5
Print J                                                    
K = 5 - 89
Print K
 

I have an Error : 49 Line : 17 Value doesn't fit into BYTE [-84] , in File : D:\pré poubelle\soustraction.bas

it is normal ! you can't do that with bascom
if you declare K as an integer you don't have error


Code:

Dim J As Byte
Dim K As Integer
J = 89 - 5
Print J                                              
K = 5 - 89
Print K

 

see the foundamentals in help

About your speudocode , you find the elegant way

JP Wink

_________________
pleasure to learn, to teach, to create
Back to top
View user's profile Visit poster's website
laborratte

Bascom Expert



Joined: 27 Jul 2005
Posts: 299
Location: Berlin

germany.gif
PostPosted: Tue Jul 02, 2019 11:49 am    Post subject: Reply with quote

Don't know if it is more elegant, but it is faster to do it in assembler by checking the carry flag and - if necessary - negate the result:

Code:
dim a as byte
dim b as byte
dim c as byte

a = 18
b = 88

gosub SubtractLowerFromHigher

print c

a = 77
b = 27

gosub SubtractLowerFromHigher

print c

end

SubtractLowerFromHigher:
!LDS r16,{a}
!LDS r17,{b}
!SUB r16,r17
!BRCC SubtractLowerFromHigher_1
!NEG r16
SubtractLowerFromHigher_1:
!STS {c},r16
!RET
Back to top
View user's profile
Arera

Bascom Member



Joined: 23 Sep 2007
Posts: 386
Location: Wuppertal, Germany

germany.gif
PostPosted: Tue Jul 02, 2019 1:28 pm    Post subject: Reply with quote

Thank you folks for your thougts!

Laborratte:
If often used, I find ASM in a sub to be quite elegant. Not for single use, but I'm sure I'll make use of it once in a while.

Marc
Back to top
View user's profile
laborratte

Bascom Expert



Joined: 27 Jul 2005
Posts: 299
Location: Berlin

germany.gif
PostPosted: Tue Jul 02, 2019 5:27 pm    Post subject: Reply with quote

Just for fun as function:
Code:
dim c as byte
CONFIG SUBMODE = NEW


function SubtractLowerFromHigher(byval a as byte, byval b as byte) as byte

'Load a
!LDD r26 , y + 2
!LDD r27 , y + 3
!ld r16,x

'Load b
!LDD r26 , y + 0
!LDD r27 , y + 1
!ld r17,x

'Substraction
!sub r16,r17

'Overflow?
!BRCC SubtractLowerFromHigher_1
'Yes: negate
!NEG R16

SubtractLowerFromHigher_1:
'Save to Result
!LDD r26 , y + 4
!LDD r27 , y + 5
!ST x,r16

end function



'Test it!

c = SubtractLowerFromHigher(18,88)

print c

c = SubtractLowerFromHigher(77,27)

print c

end


 
Back to top
View user's profile
MWS

Bascom Member



Joined: 22 Aug 2009
Posts: 2262

blank.gif
PostPosted: Tue Jul 02, 2019 7:45 pm    Post subject: Reply with quote

More simple:
Code:
C = A - B
If SREG.0 = 1 Then C = 256 - C
Back to top
View user's profile
Micha

Bascom Member



Joined: 03 Oct 2006
Posts: 57

germany.gif
PostPosted: Mon Jul 15, 2019 8:41 pm    Post subject: Reply with quote

What about this:

Code:

   Dim a as Byte
   Dim b as Byte
   Dim c as Byte

   a = 5
   b = 3

   Do

      !LDS r24,{a}
      !LDS r25,{b}

      !SUB r24,r25      ' Subtraction
      !SBIC SREG,2   ' Test if negative
      !NEG r24            ' conversation to positive value

      !STS {c},r24

      print c
      Incr b

   Loop
 


[/code]
Back to top
View user's profile
laborratte

Bascom Expert



Joined: 27 Jul 2005
Posts: 299
Location: Berlin

germany.gif
PostPosted: Tue Jul 16, 2019 5:08 pm    Post subject: Reply with quote

@ Micha:

Testing the negative flag of SREG ( !SBIC SREG,2 ) will not work with unsigned byte vars, as it represents the high-bit of the result (=sign of signed number). So it will be set if you calculate 240 - 1 = 239, because 239 represents -17 in 2's complement.

Using !sbic sreg,0 instead of !brcc does not make a difference in terms of speed on a mega device. On a Xmega it is even slower.

@ MWS:

For this specific situation your code will work, but it is - in general - not a good idea to use SREG in that way in basic code. The compiler adds several assembler commands between the actual subtraction and the if-then directive. You can't be sure that this commands doesn't affect SREG. Obviously this variant will not work:
Code:
C(I) = A - B
If SREG.0 = 1 Then C(I) = 256 - C(I)

as the compiler will generate code for calculating the memory address of C(I), which kills the carry status of the previous subtraction.

I know that you are aware of that, but other people with less knowledge about assembler will also read the forum thread.
Back to top
View user's profile
Micha

Bascom Member



Joined: 03 Oct 2006
Posts: 57

germany.gif
PostPosted: Tue Jul 16, 2019 7:04 pm    Post subject: Reply with quote

OK, this code works:

Code:
   Dim a as Byte
   Dim b as Byte
   Dim c as Byte

   a = 230
   b = 3

   Do

      !LDS r24,{a}
      !LDS r25,{b}
      !SUB r24,r25                                ' Subtraction
      !SBIC SREG,0                                ' Carry-Flag
      !NEG r24
      !STS {c},r24

      print c
      Incr b

   Loop
 
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> BASCOM-AVR All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum