Forum - MCS Electronics

Author Message
Arera

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

 Posted: Tue Jul 02, 2019 9:12 am    Post subject: absolute value of difference 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 )
Duval JP

Joined: 22 Jun 2004
Posts: 939
Location: France

Posted: Tue Jul 02, 2019 10:43 am    Post subject:

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

JP

_________________
pleasure to learn, to teach, to create
laborratte

Joined: 27 Jul 2005
Posts: 262
Location: Berlin

Posted: Tue Jul 02, 2019 11:49 am    Post subject:

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
Arera

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

 Posted: Tue Jul 02, 2019 1:28 pm    Post subject: 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
laborratte

Joined: 27 Jul 2005
Posts: 262
Location: Berlin

Posted: Tue Jul 02, 2019 5:27 pm    Post subject:

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
MWS

Joined: 22 Aug 2009
Posts: 1827

Posted: Tue Jul 02, 2019 7:45 pm    Post subject:

More simple:
 Code: C = A - B If SREG.0 = 1 Then C = 256 - C
Micha

Joined: 03 Oct 2006
Posts: 40

Posted: Mon Jul 15, 2019 8:41 pm    Post subject:

 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]
laborratte

Joined: 27 Jul 2005
Posts: 262
Location: Berlin

Posted: Tue Jul 16, 2019 5:08 pm    Post subject:

@ 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.
Micha

Joined: 03 Oct 2006
Posts: 40

Posted: Tue Jul 16, 2019 7:04 pm    Post subject:

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
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT + 1 Hour Page 1 of 1

 Jump to: Select a forum BASCOM AVR/8051----------------BASCOM-AVRBASCOM-8051BASCOM-ARDUINOShare your working BASCOM-8051 code hereShare your working BASCOM-AVR code hereBASCOM BETA-SLA BASCOM Related----------------EASY TCP/IPAVR-DOSAR7212KokkeKat FAT-free SD card libBASCOM Project Blog Other Stuff----------------VariousPCB'sRoboticsNew WebSiteAnnouncementsAVR Archive----------------BASCOM-AVR ArchiveBASCOM-8051 ArchiveBASCOM-AVR Unsupported versionsEasy TCP/IP ArchiveBASCOM-EDB
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