Menu

Error in ABS function

Theo
2014-10-28
2014-10-30
  • Theo

    Theo - 2014-10-28

    Wrong value with ABSfunction:

    #chip mega8,8
    
      #include <74LS164.h> ; include My IO 74LS164
    
     'Use LCD in 2-wire mode with 74LS164 / 74HC164
      #define LCD_IO 2
      #define LCD_DB PORTC.0            ; databit
      #define LCD_CB PORTC.1            ; clockbit
      #define LCD_NO_RW
    
      'My own IO settings
      #define SWX PORTC.2               ; input pin from pushbuttons (A,B,C,D)
      #define Led PORTC.5               ; output pin for led
      #define SoundOut PORTC.0          ; output pin for tone
      Dir SWX in                        ; set port as input for pushbuttons
    
    Locate 0,0
    Print "ABS(-127)=":print Abs(-127) ; shows 126; should be 127 (help file)
    locate 1,0
    print "ABS(127)=":print abs(127)   ; shows 127; correct
    

    Is this a typical AVR problem?

    Kind Regards
    Theo.

     
  • Theo

    Theo - 2014-10-28

    ASM File

     
  • Theo

    Theo - 2014-10-29

    Did I something wrong by the reporting of this problem?

    Theo.

     
  • Anobium

    Anobium - 2014-10-29

    No. We will look asap.

     
  • Hugh Considine

    Hugh Considine - 2014-10-30

    This is a bug that I came across myself a few days back, but hadn't released a fix for yet. The problem was with the negate operator, which is meant to invert the variable and add one, but which wasn't adding one on AVR.

    Please try replacing your copy of gcbasic.exe with the one at http://gcbasic.sourceforge.net/temp/gcbasic.exe and hopefully that will fix it. Thanks for letting us know!

     
  • pat

    pat - 2014-10-30

    compiler Bug !

    -127 is translate by FF81
    Generated Code asm;

    ldi SYSCALCTEMPA,129
    ldi SYSCALCTEMPA_H,255
    rcall FN_ABS

    FF81 XOR FFFF = 126 ' error !!!

     
  • Hugh Considine

    Hugh Considine - 2014-10-30

    pat, that code looks ok. The compiler uses Two's complement, which requires inverting and adding. So, if we negate 127, first we invert, which gives 65408 (or 0xFF80), then we add one and that gives 65409, or 0xFF81.

    As an example of why that works, suppose that we're adding 200 to -127. The result should be 73. If we add 200 to 65409, that gives 65609, which overflows to 73 (65609 AND 65535 = 73).

    (Please do point out anything that looks like a bug, I'd rather explain how something works than have bug hiding in the compiler!)

     

    Last edit: Hugh Considine 2014-10-30
  • pat

    pat - 2014-10-30

    Thanks for your quick answer.
    I'll never speak about bug now. ;-)

    this is the function ABS in ASM;

    FN_ABS:
    ;If SysCalcTempA.15 Then
    sbrs SYSCALCTEMPA_H,7
    rjmp ELSE1_1
    ;Abs = -SysCalcTempA
    com SYSCALCTEMPA
    sts ABS,SYSCALCTEMPA
    com SYSCALCTEMPA_H
    sts ABS_H,SYSCALCTEMPA_H
    inc ABS
    brne PC + 2
    inc ABS_H
    ;Else
    rjmp ENDIF1
    ELSE1_1:
    ;Abs = SysCalcTempA
    sts ABS,SYSCALCTEMPA
    sts ABS_H,SYSCALCTEMPA_H
    ;End If
    ENDIF1:
    ret

    In case SYSCALCTEMPA_H bit is 1 , that a negative number
    we make a COM function on the 2 bytes and put the result in SYSCALCTEMPA_H and SYSCALCTEMPA_L
    then copy on ABS and ABS_H
    OK

    Then ,we increment ABS and ABS_H for to correct that you explain on the previous post
    it is OK

    then we jump if there is no carry for do not increment High byte
    with that;

    brne PC + 2

    In the datasheet of Atmega8 it is write

    BRNE (branch if not equal) PC <- PC + k + 1 (page 282 on the datasheet i got)

    k is 2 => 2+1 = 3, that s mean the next 2 lines will skips !
    That mean we go at the "ELSE1_1" not at the "rjmp ENDIF1" and the inc ABS ABS_H deleted...

    It true or false ?
    Just for the fun...

     
  • pat

    pat - 2014-10-30

    The .lst have a F409

    000064 F409 BRNE PC + 2

    I don't find the code in the datasheet.
    May be it is correct if the assembler make a (PC+2) like a 1

     
  • pat

    pat - 2014-10-30

    I Found the "instruction set nomenclature"

    1111 01KK KKKk k001 K=1 => F409
    F409 mean k=1

    the code is OK !

    Sorry wrong way, good code...

     

    Last edit: pat 2014-10-30
  • Theo

    Theo - 2014-10-30

    Hugh, I installed the new gcbasic.exe.

    First everything looked OK, but after a little playing with maximum values it appears that
    the ABS function is not 100% (it's now 99%).

    First the definitions in the help file:
    Text "Variables"
    Integer: A whole number between - 32768 and 32767

    Text "ABS"
    The ABS function will computes the absolute value of a integer number therefore in the range of -32678 (I believe this must be -32768) to 32768 (and this must be 32767).

    So -32768 is a valid value according to the standard.
    Executing this line

    print ABS(-32768) ; shows -32768 ; should show 32768(but this value is no integer anymore!)
    

    produces the wrong value.

    Playing with greater values than 32767 or smaller values then-32768 (by dimension as Long) does not produce an error message but shows random values.

     

    Last edit: Theo 2014-10-30
  • pat

    pat - 2014-10-30

    I tested with the last release , i see no code probleme for this, the old i dont know...

    The limit of the signed int is - 32768 and 32767
    that mean you cannot have +32768 !

    • 32767 is the real limit of ABS function for have a positive number

    the help online is not correct

    Explanation:
    The ABS function will computes the absolute value of a integer number therefore in the range of -32678 to 32768.

    In fact the limit is -32767 32767

    When it's out of limit , why there is no messagee ? (I am agree with you)
    But the result , i think is the low part of the long value.

    If all the values that is between the limit have a good result,
    everything it 's alright, no problem.

     

    Last edit: pat 2014-10-30

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.