Menu

GCBASIC: FLOATS - Recommended for evaluation and testing

Anobium
2021-07-18
2025-08-21
1 2 3 > >> (Page 1 of 3)
  • Anobium

    Anobium - 2021-07-18

    This thread is a place holder for the final development and testing of the float capability for GCBASIC.

    News 04.04.2024 - Build 1381

    We have made great progress with the floats implementation

    Progress

    See here https://sourceforge.net/p/gcbasic/discussion/579125/thread/e777a80dfa/?limit=25#9b84.

    Download

    The Floats capability is now general release via GCSTUDIO download. Linux build will follow in late April 24.

     

    Last edit: Anobium 2024-04-04
  • Anobium

    Anobium - 2021-07-18

    Issues

    Please respond this post with new ( or updating ) issues. Please post the issue and the source code.

     

    Last edit: Anobium 2021-07-18
    • Anobium

      Anobium - 2021-07-18

      Basic maths is failing ( from Bill Roth).

      Tests are like shown below - all tests should return 199.

      MyDouble = 100.140 + 99.650
      MyDouble = 100.14 + 99.65
      

      Great Cow BASIC
      Print FLOAT TEST
      18F27Q43

      100 MyLong from Double should return 199.79 = 0
      110 MyLong from Double should return 199.79 = 100
      120 MyLong from Double should return 199.792 = 199
      200 MyLong from Single should return 199.79 = 204472
      201 MyLong from Single should return 199.79 = 204472
      210 MyLong from Single should return 199.79 = 100
      220 MyLong from Single should return 199.792 = 199


      MySingle = (-11.5) + (-11.5)
      MyInteger = MySingle
      Hserprint MyINteger
      'This returns -23 at the terminal ( correct)

      HSerprintCRLF
      MySingle = (-11.0) + (-11.5)
      MyInteger = MySingle
      Hserprint MyINteger
      'This returns -11 at the terminal (incorrect)

      Simple float maths using Single or Double is failing. Accepting the Help works but the attached code fails. The two example above return

      pp Bill

       

      Last edit: Anobium 2021-08-14
      • Anobium

        Anobium - 2021-07-18

        Basic maths using subtraction is falling.

        Similar result to addition errors only 3 digit decimals is correct with only two of the tests working as expected.

        Posted by Evan

         
        • Anobium

          Anobium - 2021-07-19

          Rotate scope of operations.

          My notes say rotate for "advance variables", therefore, I assumed all four advanced types.

          The compiler seems to only support longInt and UlongInt. See code segment from compiler.

          ....
                'Check var type
                If Not IsIntType(VarType) Then 'Error
                  Temp = Message("BadCommandType")
                  Replace Temp, "%command%", "Rotate"
                  Replace Temp, "%type%", VarType
                  LogError Temp, Origin
                  Goto CompileNextRotate
                End If
          ....
          
          Function IsIntType(InType As String) As Integer
            'Returns true (-1) if input type is an integer variable
            Dim ThisType As String
            ThisType = LCase(InType)
          
            Select Case ThisType
              Case "const", "byte", "word", "integer", "long", "ulongint", "longint": Return -1
              Case Else: Return 0
            End Select
          
          End Function
          

          What is correct ? Just the integer types of longInt and UlongIt and/or floats and the compliler needs updating.


          Help now shows only integer types of longInt and UlongIt until this is resolved.

           

          Last edit: Anobium 2021-07-19
          • Anobium

            Anobium - 2021-07-19

            Negate scope of operations.

            My notes say Negate for "advance variables", therefore, I assumed all four advanced types.

            The compiler support is not working.

            What is correct ? Just the integer types of longInt and UlongIt and/or floats and the complier needs updating.

            Help currenly shows all four advanced types are supported.

            What is the correct ? just longInt and UlongInt ?

             
          • Anobium

            Anobium - 2021-07-19

            Subtraction issue.

            There is some weird maths happening. 0-3.142 = 6.nnnn, 0-10=20.mmm ???
            Yet other numbers work 0-1, 0-4 etc. I cannot determine a sequence - most be broken in the asm

            Bug. Basic maths are incorrect.

            Evan

            Example code.

            HSerPrintCRLF 2
            HSerPrint "Maths test "
            HSerPrintCRLF 2
            
            Dim ccount as single
            Dim calcresult as double
            Dim result as Integer
            
            HSerPrintCRLF
            HSerPrint "Use floats with negate"
            HSerPrintCRLF
            
            'Assign a value to a double variable
            ccount   = 3.142
            'Convert Double to Long to get the result
            result = ccount
            HSerPrint left(strInteger(result)+"        ", 8 )
            HSerPrintCRLF 2
            
            'simple maths ....
            calcresult = 0 - ccount
            
            'Convert Double to Long to get the result
            result = calcresult
            HSerPrint left(strInteger(result)+"        ", 8 )
            HSerPrintCRLF 2
            
             

            Last edit: Anobium 2021-07-20
    • Anobium

      Anobium - 2021-07-19

      Issue - What are the essential functions ?

      If doing math with floats you need to use either the single or double variable type.

      The float data type has only 6-7 [ needs confirmation by Hugh] decimal digits of precision. That means the total number of digits, not the number to the right of the decimal point.

      Floating point numbers are not exact [ Hugh.. is this true ?] , and may yield strange results when compared using conditions (IF etc). For example 6.0 / 3.0 may not equal 2.0. Users should instead check that the absolute value of the difference between the numbers is less than some small number.

      As floating point numbers are not exact we need the following functions:

      INT() ..  
      ROUND()
      

      Conversion from floating point to integer math results in truncation. This is ready functional.

      dim mySingleVar as Single
      mySingleVar = 2.9  'A float type variable
      
      dim myLongVar as Long
      myLongVar = mySingleVar ' will set myLongVar to 2
      

      but, we will need to ensure users do not mess up. Should we add INT ( Single or Double ) ?

      myLongVar = INT( mySingleVar )
      

      And, users may want round off during the conversion process, users need to add 0.5: As follows:

      mySingleVar = 2.9
      myLongVar= mySingleVar + [single]0.5  '3
      

      but, we will need to ensure users do not mess up. Should we add ROUND( Single or Double ) ?

      mySingleVar = 2.9
      myLongVar = ROUND(mySingleVar) '3


      Or, we can decide not to included INT() & ROUND() leaving the users to use the intger assignment and add 0.5 for INT() and ROUND() respectively.


      Your thoughts?

       

      Last edit: Anobium 2021-07-19
    • Anobium

      Anobium - 2021-07-21

      longInt and UlongInt do not accept full range. It is assummed that all advanced variables have the same constraint... will not accept full range.

      Compiler will not accept the complete (full range) of values when using an assignment from a constant string.

      We need to test the extremes on all four advanced variables.

       

      Last edit: Anobium 2021-07-21
  • Anobium

    Anobium - 2021-07-18

    Solutions that work !! :-)

    Please respond to this post with programs that work!

     

    Last edit: Anobium 2021-07-18
    • Anobium

      Anobium - 2021-07-18

      Working pseudo multiplication.

      only works with specific source numeric values!!

      This shows pseudo multiplication using repeat-end repeat but using floats is slow.

      This code is shown in the help.

       

      Last edit: Anobium 2021-07-19
  • mmotte

    mmotte - 2021-07-19

    Whats up? Do we have floats? and floating point math? if so, hooray!

     
    • Anobium

      Anobium - 2021-07-20

      @mmotte - Yes. early days but we have stability in the compiler to review and test floats.

      Look at the posts and the Help to see state of play but please do try to use.

      Early days.

       
  • William Roth

    William Roth - 2021-07-19

    Issue - Micro controller stops execution under certain conditions.

    The Program below will not complete  "TEST_LOOP2"   
    "TEST_LOOP3"  Never Executes 
    
        #CHIP  18f27q43, 32
        #CONFIG MCLRE = ON,  WDTE = OFF
        #OPTION Explicit
    
        #DEFINE LED PORTC.3
        Dir LED OUT 
    
        '''Variables
        Dim MyDouble as Double
    
        Wait 1 s
    
        TEST_LOOP1:  'Verify LED with 3 Flashes
        Repeat 3
          Pulseout PORTC.3, 200 ms
          Wait 200 ms
        End Repeat
    
        Wait 1 s
    
        TEST_LOOP2:  'This loop does not complete 2 iterations
        Repeat 2
    
           MyDouble = 10.00 - 3.140
            MyDouble = 0 - 9.10
    
        End Repeat
    
        TEST_LOOP3:  'Flash 10 times ( never gets here)
        Repeat 10
           Pulseout PORTC.3, 200 ms
           Wait 200 MS
        End Repeat
    
         END
    
     

    Last edit: Anobium 2021-07-20
    • Anobium

      Anobium - 2021-07-20

      Analysis - the trailing zero in the string constants messes up the compiler. Removing the trailing zeros generates ASM that looks ok. Could be the '.00' after the '10' but anyway this is not being processed correctly.

      @williamroth

      Bug - string constants used to assign values to a double that have trailing zeros does not generate valid asm.

       

      Last edit: Anobium 2021-07-20
  • Clint Koehn

    Clint Koehn - 2021-08-13

    I think this works. I don't know if this helps you or not. This returns component parts of a single precision number.

    Sub ExtractSngParts(sng as Single, sgn as Byte, exp as Byte, mantissa as Long)
      dim tmplong as Long
    
      MoveSngToLong sng, tmplong
    
      mantissa = tmplong & 0x7FFFFF
      tmplong = FnLSR(tmplong, 23)
      exp = tmplong & 0xFF
      tmplong = FNLSR(tmplong,8)
      sgn = tmplong
    
    End Sub
    
    Sub MoveSngToLong(sngn1 as Single, snum1 as Long)
      'Moves 4 byte single precision to 4 byte Long
      ' I haven't found any other way to do this
    
      snum1.0 = sngn1.0:snum1.1 = sngn1.1:snum1.2 = sngn1.2:snum1.3 = sngn1.3
      snum1.4 = sngn1.4:snum1.5 = sngn1.5:snum1.6 = sngn1.6:snum1.7 = sngn1.7
    
      snum1.8 = sngn1.8:snum1.9 = sngn1.9:snum1.10 = sngn1.10:snum1.11 = sngn1.11
      snum1.12 = sngn1.12:snum1.13 = sngn1.13:snum1.14 = sngn1.14:snum1.15 = sngn1.15
    
      snum1.16 = sngn1.16:snum1.17 = sngn1.17:snum1.18 = sngn1.18:snum1.19 = sngn1.19
      snum1.20 = sngn1.20:snum1.21 = sngn1.21:snum1.22 = sngn1.22:snum1.23 = sngn1.23
    
      snum1.24 = sngn1.24:snum1.25 = sngn1.25:snum1.26 = sngn1.26:snum1.27 = sngn1.27
      snum1.28 = sngn1.28:snum1.29 = sngn1.29:snum1.30 = sngn1.30:snum1.31 = sngn1.31
    End Sub
    

    Later,
    Clint

     
    • Anobium

      Anobium - 2021-08-14

      @ckoehn Can you post an example piece of code to help me understand usage? Cheers

       
  • Clint Koehn

    Clint Koehn - 2021-08-14

    I finally got out of bed, it's 7am here. I'll try and do that this morning sometime. I think I read Single Precision addition and subtraction work, but I went ahead and made my own functions just to get a better understanding of the algorithms. I couldn't get "&" to work on a Single number, that's why I had to transfer it to a Long like I did.

     
  • Clint Koehn

    Clint Koehn - 2021-08-17

    Here is what I've been doing the last few days....

    I can't seem to add attachments so....

    #chip 18F14K22,64     'PIC18F14K22 running at 16 MHz x 4
    
    '-------- serial port setup ------------------------------------------
    #define SerOut PORTB.7 'radio tx
    
    '-------- interrupt Handler for communications -----------------------
    #define USART_BAUD_RATE 9600
    #define USART_TX_BLOCKING
    
    #include <maths.h>
    
    '---------- misc variable definition ---------------------------------
    dim sNumA, sNumB, sNumC as Single
    dim lMantissa, lNumA, lNumB, lNumC as Long
    dim bSign, bExponent as Byte
    dim fStr as string * 33
    
    '---------------------------------------------------------------------
    wait 200 ms
    
    sNumA = 7.589
    
    sNumB = 18.1286
    
    ' single precision addition works
    sNumC = sNumA + sNumB 'should be 25.7176, but is 25.7175979614
    MoveSngToLong sNumC, lNumC
    fStr = LongtoBin(lNumC)
    HSerPrint "WORKS Single addition 7.589 + 18.1286 = ":HSerPrint fStr:HSerSend 13
    
    ' single precision subtraction works
    sNumC = sNumB - sNumA 'should be 10.5396, but is 10.5396003723
    MoveSngToLong sNumC, lNumC
    fStr = LongtoBin(lNumC)
    HSerPrint "WORKS Single subtraction 18.1286 - 7.589 = ":HSerPrint fStr:HSerSend 13
    
    ' single precision subtraction works
    sNumC = sNumA - sNumB 'should be -10.5396, but is -10.5396003723
    MoveSngToLong sNumC, lNumC
    fStr = LongtoBin(lNumC)
    HSerPrint "WORKS Single subtraction 7.589 - 18.1286 = ":HSerPrint fStr:HSerSend 13
    
    '************** NATIVE MULTIPLY DOESN'T WORK **************************
    snumC = sNumA * sNumB
    MoveSngToLong snumC, lNumC
    fStr = LongtoBin(lNumC)
    HSerSend 13: HSerPrint "DOESN't WORK Single multiplication 7.589 * 18.1286 = ":HSerPrint fStr:HSerSend 13
    
    ' I followed how this https://www.cs.uaf.edu/2000/fall/cs301/notes/notes/node52.html
    ' website sait to multiply 2 single precision numbers.  My answer varied
    ' from what the converter said, so I don't know if the converter is
    ' wrong (didn't look like it was) or if the website was wrong.
    ' the website was: 137.5802154541015625
    '  I came up with: 137.577957153
    
    '--------------------------------------------------------------------------
    ' copy the binary into
    ' the "Binary Representation" here: https://www.h-schmidt.net/FloatConverter/IEEE754.html
    ' I guess this is as close as single precision gets.
    
    ' this is my multiply routine
    MultiplySng sNumA, sNumB, sNumC
    MoveSngToLong sNumC, lNumC
    fStr = LongtoBin(lNumC)
    HSerSend 13: HSerPrint "WORKS My Single multiplication 7.589 * 18.1286 = ":HSerPrint fStr:HSerSend 13
    
    'this shows the single variable parts, sign, exponent and mantissa
    ShowData sNumC, "Single Precision part of above answer
    
    Do
      'loop forever
    Loop
    
    Sub ShowData(in sNumA as Single, Optional fStr as String = "")
      ExtractSingleParts sNumA, bSign, bExponent, lMantissa
    
      HSerPrint fStr: HSerSend 13
      HSerPrint "Sign: "
      HSerPrint bSign
      HSerSend 13
      HSerPrint "Exp: "
      HSerPrint bExponent
      HSerSend 13
      HSerPrint "Mantissa: "
      HSerPrint lMantissa
      HSerSend 13
      hsersend 13
    
    End Sub
    
    Sub ShowLongParts(in lTemp as Long)
      dim bSignx, bExponentx as Byte
      dim lMantissax as Long
    
      lMantissax = lTemp & 0x7FFFFF
      lTemp = FnLSR(lTemp, 23)
      bExponentx = lTemp & 0xFF
      lTemp = FNLSR(lTemp,8)
      bSignx = lTemp
    
      HSerSend 13
      HSerPrint "Sign: "
      HSerPrint bSignx
      HSerSend 13
      HSerPrint "Exp: "
      HSerPrint bExponentx
      HSerSend 13
      HSerPrint "Mantissa: "
      HSerPrint lMantissax
      HSerSend 13
      hsersend 13
    
    End Sub
    
    '---------------------------------------------------------------------
    Sub ExtractSingleParts(in snum as Single, out bSign as Byte, out bExponent as Byte, out lMantissa as Long)
      dim lTemp as Long
    
      MoveSngToLong snum, lTemp  'transfer from single to long to use math logic
    
      lMantissa = lTemp & 0x7FFFFF
      lTemp = FnLSR(lTemp, 23)
      bExponent = lTemp & 0xFF
      lTemp = FNLSR(lTemp,8)
      bSign = lTemp
    
    End Sub
    
    Sub AssembleSingleParts( snum as Single, in bSign as Byte, in bExponent as Byte, in lMantissa as Long)
      dim lTemp as Long
    
      lTemp = bSign
      lTemp = FnLSL(lTemp,8) + bExponent
      lTemp = FNLSL(lTemp,23) + (lMantissa & 0x7FFFFF) + 1
    
      MoveLongToSng lTemp, snum  'transfer from long to single
    
    End Sub
    
    Sub MoveSngToLong(in snum as Single, lnum as Long)
      'Moves 4 byte single precision to 4 byte Long
    
      lnum.0 = snum.0:lnum.1 = snum.1:lnum.2 = snum.2:lnum.3 = snum.3
      lnum.4 = snum.4:lnum.5 = snum.5:lnum.6 = snum.6:lnum.7 = snum.7
    
      lnum.8 = snum.8:lnum.9 = snum.9:lnum.10 = snum.10:lnum.11 = snum.11
      lnum.12 = snum.12:lnum.13 = snum.13:lnum.14 = snum.14:lnum.15 = snum.15
    
      lnum.16 = snum.16:lnum.17 = snum.17:lnum.18 = snum.18:lnum.19 = snum.19
      lnum.20 = snum.20:lnum.21 = snum.21:lnum.22 = snum.22:lnum.23 = snum.23
    
      lnum.24 = snum.24:lnum.25 = snum.25:lnum.26 = snum.26:lnum.27 = snum.27
      lnum.28 = snum.28:lnum.29 = snum.29:lnum.30 = snum.30:lnum.31 = snum.31
    End Sub
    
    Sub MoveLongToSng(in lnum as Long, snum as Single)
      'Moves 4 byte Long to 4 byte single precision
    
      snum.0 = lnum.0:snum.1 = lnum.1:snum.2 = lnum.2:snum.3 = lnum.3
      snum.4 = lnum.4:snum.5 = lnum.5:snum.6 = lnum.6:snum.7 = lnum.7
    
      snum.8 = lnum.8:snum.9 = lnum.9:snum.10 = lnum.10:snum.11 = lnum.11
      snum.12 = lnum.12:snum.13 = lnum.13:snum.14 = lnum.14:snum.15 = lnum.15
    
      snum.16 = lnum.16:snum.17 = lnum.17:snum.18 = lnum.18:snum.19 = lnum.19
      snum.20 = lnum.20:snum.21 = lnum.21:snum.22 = lnum.22:snum.23 = lnum.23
    
      snum.24 = lnum.24:snum.25 = lnum.25:snum.26 = lnum.26:snum.27 = lnum.27
      snum.28 = lnum.28:snum.29 = lnum.29:snum.30 = lnum.30:snum.31 = lnum.31
    End Sub
    
    '---------------------------------------------------------------------
    Sub SingleToLong(lNumA as Long, in bPrecision as byte, out bSign as Byte)
      '-----------------------------------------------------
      ' bSign - the sign is returned in this variable
      ' sNumA - single bPrecisionision in, long variable out
      ' bPrecision - number of digits of bPrecisionision (e.i. 3 = 1000)
      '-----------------------------------------------------
    
      dim mantissa as Long
      dim exponent as Byte
      dim lng as Long
      dim mlng as Long
    
      mlng = lNumA
      'mlng = FnLSR(mlng, 7)
      mantissa = mlng & 0x7FFFFF
      mlng = FnLSR(mlng, 23)
      exponent = mlng & 0xFF
      bSign = FnLSR(mlng, 8) ' 1 is negative, 0 is positive
    
      lng = Power(10, bPrecision)
      mlng = mantissa * lng
      mlng += 0x800000 * lng
      mlng = (mlng / 0x800000)
    
      if exponent < 127 then
        'fractional - divide
        HSerPrint "<": HSerSend 13
        exponent = 127 - exponent
        nlng = (mlng / Power(2, exponent)) + 1
      else
        'whole number - multiply
        HSerPrint ">": HSerSend 13
        exponent = exponent - 127
        lng = (mlng * Power(2, exponent)) + 1
      end if
    
      lNumA = lng
    End Sub
    
    sub hFormat(in lNumA as Long, in bPrec as Byte)
      dim numx, numy as Byte
    
      fStr = " " + Str(lNumA)
      if bSign = 1 then
        fStr(1) = "-"
      end if
    
      fStr(0) ++  ' add for decimal point
    
      numy = fStr(0)
    
      for numx = 1 to bPrec
        fStr(numy) = fStr(numy - 1)
        numy --
      next numx
      fStr(numy) = "."
    
    End Sub
    
    '-------------------------------------------------------------
    Sub MultiplySng(in sNumA as Single, in sNumB as Single, out sAnswer as Single)
      dim sgn1, sgn2, exp1, exp2 as Byte
      dim mant1, mant2, mant_result, lAnswer as Long
      dim lSingle_result as Long
      dim lNumA, lNumB as Long
    
      ExtractSingleParts sNumA, sgn1, exp1, mant1 'get single precision parts
      ExtractSingleParts sNumB, sgn2, exp2, mant2 'get single precision parts
    
      mant1.23 = 1  'enable hidden bit
      mant2.23 = 1  'enable hidden bit
    
      MultiLong mant1, mant2  'multiply mantissa
    
      sgn_result = sgn1 # sgn2 'xor signs
      exp_result = exp1 + exp2 + 0b10000001 'add exponents - 127
    
      mant1 = FnLSL(mant1, 16)
      mant2 = FnLSR(mant2, 16)  'this leaves 9 bits left in the right long variable
    
      mant_result = mant1 | mant2
      mant_result = FnLSR(mant_result,7)
      if mant_result.24 = 1 then            ' if hidden bit carried
        exp_result ++                       ' increase exponent
        mant_result = FnLSR(mant_result,1)  ' shift result right 1 bit
      end if
    
      mant_result = mant_result & 0x7FFFFF 'pull out the right 23 bits
    
      AssembleSingleParts sAnswer, sgn_result, exp_result, mant_result
    
    End Sub
    
    Sub MultiLong(lng1 as long, lng2 as long)
      dim tmp(9) as Byte
      dim ans(5) as Word
      dim w1 as Word
      dim w2 as Word
      dim w3 as Word
      dim w4 as Word
    
      lng1E = lng1_E:lng1U = lng1_U:lng1H = lng1_H:lng1B = (lng1 & 0xFF)
    
      ptr = 1
      tmp(0) = 8
      ans(0) = 4
    
      for cnt = 1 to 8
        tmp(cnt) = 0
      next cnt
    
      for cnt = 1 to 4
    
        lng2B = (lng2 & 0xFF)
    
        ans(1) = lng1B * lng2B
        btmp = FnLSR( ans(1), 8)
        ans(2) = [word]lng1H * lng2B + btmp
        btmp = FnLSR( ans(2), 8)
        ans(3) = [word]lng1U * lng2B + btmp
        btmp = FnLSR( ans(3), 8)
        ans(4) = [word]lng1E * lng2B + btmp
    
        btmp = ans(1)
        w1 = [word]btmp + tmp(ptr)
        tmp(ptr) = tmp(ptr) + btmp'ans(1)
        b1 = FnLSR(w1, 8)
        ptr ++
    
        btmp = ans(2)
        w2 = [word]btmp + tmp(ptr)
        tmp(ptr) = tmp(ptr) + btmp + b1
        b2 = FnLSR(w2, 8)
        ptr ++
    
        btmp = ans(3)
        w3 = [word]btmp + tmp(ptr)
        tmp(ptr) = tmp(ptr) + btmp + b2
        b3 = FnLSR(w3, 8)
        ptr ++
    
        btmp = ans(4)
        w4 = ans(4)
        tmp(ptr) = tmp(ptr) + btmp + b3
        b4 = FnLSR(w4, 8)
        ptr ++
    
        tmp(ptr) = b4
        ptr = ptr - 3
    
        lng2 = FnLSR(lng2,8)  'move to next Byte
    
      next cnt
    
      'move to long variables
      lng1 = tmp(8):lng1 = FnLSL(lng1,8) + tmp(7):lng1 = FnLSL(lng1,8) + tmp(6):lng1 = FnLSL(lng1,8) + tmp(5)
      lng2 = tmp(4):lng2 = FnLSL(lng2,8) + tmp(3):lng2 = FnLSL(lng2,8) + tmp(2):lng2 = FnLSL(lng2,8) + tmp(1)
    
    End Sub
    
    Sub SubNum(in lNumA as Long, in lNumB as Long, lAnswer as Long)
      'invert second sign
      lNumB.31 = !lNumB.31
    
      'then add
      AddNum lNumA, lNumB, lAnswer
    
    End Sub
    
    Sub AddNum(in lNumA as Long, in lNumB as Long, lAnswer as Long)
      dim exp1, exp2, exp_result, sgn1, sgn2, sgn_result as Byte
      dim mant1, mant2, mant_result as Long
      dim lSingle_result as Long
    
      mant1 = lNumA & 0x7FFFFF
      lNumA = FnLSR(lNumA, 23)
      exp1 = lNumA & 0xFF
      lNumA = FNLSR(lNumA, 8)
      sgn1 = lNumA
    
      mant2 = lNumB & 0x7FFFFF
      lNumB = FnLSR(lNumB, 23)
      exp2 = lNumB & 0xFF
      lNumB = FnLSR(lNumB,8)
      sgn2 = lNumB
    
      if exp1 > exp2 then
        'exp2 needs adjustment
        sgn_result = exp1 - exp2
    
        if sgn_result > 23 then
          'answer is larger number
          lSingle_result = lNumA
        else
          mant2 = mant2 + 0x800000  'add hidden 1
          mant2 = FnLSR(mant2, sgn_result)
          exp_result = exp1
    
          if sgn1 = 1 then
            ' do 2's complement
            mant1 = !mant1
            mant1 += 1
          end if
    
          if sgn2 = 1 then
            ' do 2's complement
            mant2 = !mant2
            mant2 += 1
          end if
          mant_result = mant1 + mant2
          lSingle_result = sgn1
          lSingle_result = FnLSL(lSingle_result, 8)
          lSingle_result += exp_result
          lSingle_result = FnLSL(lSingle_result, 23)
          lSingle_result += mant_result
        end if
      else
        'exp1 needs adjustment
        sgn_result = exp2 - exp1
    
        if sgn_result > 23 then
          'answer is larger number
          lSingle_result = lNumB
        else
          mant_result = mant1 + 0x800000  'add hidden 1
          mant1 = FnLSR (mant_result, sgn_result)
          exp_result = exp2
    
          if sgn1 = 1 then
            ' do 2's complement
            mant1 = !mant1
            mant1 += 1
          end if
    
          if sgn2 = 1 then
            ' do 2's complement
            mant2 = !mant2
            mant2 += 1
          end if
          mant_result = mant1 + mant2
          lSingle_result = sgn2
          lSingle_result = FnLSL(lSingle_result, 8)
          lSingle_result += exp_result
          lSingle_result = FnLSL(lSingle_result, 23)
          lSingle_result += mant_result
        end if
      end if
      lAnswer = lSingle_result
    End Sub
    

    Later,
    Clint

     
  • Anobium

    Anobium - 2021-08-17

    @Clint. Thank you for your great analysis. I know you have spent many,any hours on this key baseline work. We should have done this work up front, but, we did not.

    I have asked Hugh to review the whole thread as we have a good analysis of the floats implementation. I emailed Hugh just now.

    Again, thank you.

     
  • Clint Koehn

    Clint Koehn - 2021-08-18

    Here is another file to try. Everything should work. I added a HSerPrintSng sub to print single precision numbers out. It is limited to what can fit into a long variable. Precision is lost due to Single precision inaccuracies, but isn't too bad.

    Later,
    Clint

     
    • Anobium

      Anobium - 2021-08-19

      The calc 1356.249088 * 236.249984 = 320339.968 should be 320413.8253400146. So, an error of 73.857340014592.

      Should we be concerned?

       
      • Chris Roper

        Chris Roper - 2021-08-19

        Depends if the error is in your favor or the Bank's :)

         
        • Anobium

          Anobium - 2021-08-19

          LOL....

           
1 2 3 > >> (Page 1 of 3)

Log in to post a comment.