Announcement

Collapse
No announcement yet.

Single Precision Variable Cleared When Adding Zero

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Single Precision Variable Cleared When Adding Zero

    Hi All,

    I have a very strange problem. The program is too large to post and needs external data to run. But It seems that when the code adds zero to a SINGLE variable it gets set to zero also any further instructions to add to that variable are not being added and from then on the variable stays at zero.

    The first column is the tally variable, the second is the value being added and the third is the result. Carries to the next line and so on.
    [code]
    0________________ 582.34 ___________________ 582.34
    582.34 ___________ 113.61 ___________________ 695.95
    695.95 ___________ 43.3134 __________________ 739.2634
    739.2634 _________ 4.273837 _________________ 743.5373
    743.5373 _________ 167.41____________________ 910.9473
    910.9473 _________ 9.141979 _________________ 920.0892
    920.0892 _________ 549.53 ___________________ 1469.619
    1469.619 _________ 166.275 __________________ 1635.894
    1635.894 _________ 182.275 __________________ 1818.169
    1818.169 _________ 0 _______________________ 0 <<<<<<<<<<<<<< This Column Should Be 1818.169
    0 ________________ 0 _______________________ 0
    0 ________________ 101.685 _________________ 0
    0 ________________ 96.59 __________________ 0
    [code]

    I've looked over the code many times and totally baffled.

    Just a slim chance wondering if anyone else has had a similar problem?

    This is a small section that performing the above.
    Code:
        Revenue_Percentage_Prof_Diff_Factor = VAL( trans_history_Results_Set_Array( TL3, 4 )) / ( trans_entries_calc_total_sale_Ex_VAT - trans_entries_calc_total_cost_Ex_VAT )
                            '
                            FOR TL6 = 1 TO Prod_Pack_Transaction_Array_Qty
                                '
                                TSingle1 = Prod_Pack_Transaction_Total_Sales_Ex_VAT_Array( TL6 ) - Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 )
                                '
                                Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 ) = Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 ) + TSingle1 - ( TSingle1 * Revenue_Percentage_Prof_Diff_Factor )
                                '
                                IF Prod_Pack_Transaction_Array_Master_Qty = 0 THEN
                                    '
                                    TL7 = 0
                                    '
                                ELSE
                                    '
                                    ARRAY SCAN Prod_Pack_Transaction_id_Master_Array( ), _
                                      = Prod_Pack_Transaction_id_Array( TL6 ), _
                                      TO TL7
                                    '
                                END IF
                                '
                                IF TL7 = 0 THEN
                                    '
                                    INCR Prod_Pack_Transaction_Array_Master_Qty
                                    '
                                    TL7 = Prod_Pack_Transaction_Array_Master_Qty
                                    '
                                    REDIM PRESERVE Prod_Pack_Transaction_id_Master_Array( 1 TO TL7 ) AS LONG
                                    REDIM PRESERVE Prod_Pack_Transaction_Total_Costs_Master_Array( 1 TO TL7 ) AS SINGLE
                                    REDIM PRESERVE Prod_Pack_Transaction_Total_Sales_Master_Array( 1 TO TL7 ) AS SINGLE
                                    '
                                    Prod_Pack_Transaction_id_Master_Array( TL7 ) = Prod_Pack_Transaction_id_Array( TL6 )
                                    '
                                END IF
                                '
                   if Prod_Pack_Transaction_id_Master_Array(TL7) = -1 then
                    '
                    print Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ),Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 ),
                    '
                  end if
                  '
                                Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ) = Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ) + Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 )
                  Prod_Pack_Transaction_Total_Sales_Master_Array( TL7 ) = Prod_Pack_Transaction_Total_Sales_Master_Array( TL7 ) + Prod_Pack_Transaction_Total_Sales_Ex_VAT_Array( TL6 )
                                '
                  if Prod_Pack_Transaction_id_Master_Array(TL7) = -1 then
                    '
                    print Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 )
                    '
                  end if
                  '
                            NEXT TL6

  • #2
    I think you are having a precision problem, a single can only show 6 digits maximum for display. From the help system.
    While Single-precision numbers can represent both enormous and microscopic values, they are limited to six digits of precision. In other words, Single-precision does a good job with figures like $451.21 and $6,411.92, but $671,421.22 cannot be represented exactly because it contains too many digits. Neither can 234.56789 or 0.00123456789. A Single-precision representation will come as close as it can in six digits: $671,421, or 234.568, or 0.00123457. Depending on your application, this rounding off can be a trivial or crippling deficiency. Like most modern compilers, Classic PowerBASIC uses the IEEE standard for all floating-point arithmetic.

    I could be wrong but try using a double and see if it adds correctly.

    KS

    Comment


    • #3
      Far to complicated to analyse with the data available, but I'd bet it's a logic or bounds problem, not a precision problem. Lots of conditional variable manipulation. Could you have a hidden "divide by zero" (in Revenue_Percentage_Prof_Diff_Factor)?

      This is where debug code that logs the results of each calculation pays dividends.

      Comment


      • #4
        Please post something that compiles.
        Array not dimensioned before array scan in this snippet and no test data.
        Code:
        DEFSNG A-Z
        FUNCTION PBMAIN () AS LONG
         Revenue_Percentage_Prof_Diff_Factor = VAL( trans_history_Results_Set_Array( TL3, 4 )) / ( trans_entries_calc_total_sale_Ex_VAT - trans_entries_calc_total_cost_Ex_VAT)
         FOR TL6 = 1 TO Prod_Pack_Transaction_Array_Qty
          TSingle1 = Prod_Pack_Transaction_Total_Sales_Ex_VAT_Array( TL6 ) - Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 )
          Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 ) = Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 ) + TSingle1 - ( TSingle1 * Revenue_Percentage_Prof_Diff_Factor )
          IF Prod_Pack_Transaction_Array_Master_Qty = 0 THEN
           TL7 = 0
          ELSE
           ARRAY SCAN Prod_Pack_Transaction_id_Master_Array( ), = Prod_Pack_Transaction_id_Array( TL6 ), TO TL7
          END IF
          IF TL7 = 0 THEN
           INCR Prod_Pack_Transaction_Array_Master_Qty
           TL7 = Prod_Pack_Transaction_Array_Master_Qty
           REDIM PRESERVE Prod_Pack_Transaction_id_Master_Array( 1 TO TL7 ) AS LONG
           REDIM PRESERVE Prod_Pack_Transaction_Total_Costs_Master_Array( 1 TO TL7 ) AS SINGLE
           REDIM PRESERVE Prod_Pack_Transaction_Total_Sales_Master_Array( 1 TO TL7 ) AS SINGLE
           Prod_Pack_Transaction_id_Master_Array( TL7 ) = Prod_Pack_Transaction_id_Array( TL6 )
          END IF
          IF Prod_Pack_Transaction_id_Master_Array(TL7) = -1 THEN
           PRINT Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ),Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 ),
          END IF
          Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ) = Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ) + Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 )
          Prod_Pack_Transaction_Total_Sales_Master_Array( TL7 ) = Prod_Pack_Transaction_Total_Sales_Master_Array( TL7 ) + Prod_Pack_Transaction_Total_Sales_Ex_VAT_Array( TL6 )
          IF Prod_Pack_Transaction_id_Master_Array(TL7) = -1 THEN
           PRINT Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 )
          END IF
         NEXT tl6
        END FUNCTION
        https://www.tesla.com/roadster

        Comment


        • #5
          ?? array indexes as floating point vs integer ??
          Dale

          Comment


          • #6
            It isn't that. I just added DEFSNG A-Z in an attempt to compile Steve's code.
            It is probably an array out of bounds as mentioned by Stuart.
            TL6 or or T7 could be anything.
            https://www.tesla.com/roadster

            Comment


            • #7
              TL6 or or T7 could be anything.
              Steve didn't say either in the very limited code posted. (though it should have given a compile time error if he'd used SINGLEs for indexes.)

              -----------------------------------------------------------
              from Help for PBWin 10 and PBCC 6
              The DEFtype statement may not be supported in future editions of PowerBASIC, so we recommend explicit variable declarations, ...
              IMO it should be gone already ... ah well

              Cheers,
              Dale

              Comment


              • #8
                It seems to me that he might be printing before assigning the values. The following code after REDIMming:
                Code:
                 
                  if Prod_Pack_Transaction_id_Master_Array(TL7) = -1 then                 '                 print Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ),Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 ),                 '               end if
                Code:
                if Prod_Pack_Transaction_id_Master_Array(TL7) = -1 then                 '                 print Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ),Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 ),                 '               end if               '                             Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ) = Prod_Pack_Transaction_Total_Costs_Master_Array( TL7 ) + Prod_Pack_Transaction_Total_Costs_Ex_VAT_Array( TL6 )               Prod_Pack_Transaction_Total_Sales_Master_Array( TL7 ) = Prod_Pack_Transaction_Total_Sales_Master_Array( TL7 ) + Prod_Pack_Transaction_Total_Sales_Ex_VAT_Array( TL6 )
                Rod
                "To every unsung hero in the universe
                To those who roam the skies and those who roam the earth
                To all good men of reason may they never thirst " - from "Heaven Help the Devil" by G. Lightfoot

                Comment


                • #9
                  Originally posted by Dale Yarker View Post
                  Steve didn't say either in the very limited code posted. (though it should have given a compile time error if he'd used SINGLEs for indexes.)
                  A quick experiment suggests that PB rounds floating point values to integers (using bankers rounding as per the ROUND function) when using them as array indices. No error generated.

                  Comment


                  • #10
                    Does #DEBUG ERROR ON and #DEBUG DISPLAY ON do anything to help?

                    Comment


                    • #11
                      This works fine!

                      Code:
                      #COMPILE EXE
                      #DIM ALL
                      GLOBAL x AS SINGLE
                      FUNCTION PBMAIN () AS LONG
                      x = 1818.169
                      PRINT x
                      x= x+0
                      PRINT x
                      WAITKEY$
                      END FUNCTION
                      Latest PBCC, Windows 10

                      Unlikely in the extreme to be a calculation problem

                      So apply the first law of debugging namely 'look somewhere else'

                      [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                      Kerry Farmer

                      Comment


                      • #12
                        A quick experiment suggests that PB rounds floating point values to integers (using bankers rounding as per the ROUND function) when using them as array indices. No error generated.
                        Interesting.

                        From Help
                        Individual array elements are selected with subscripts or index numbers, which are Long-integer expressions within parentheses to the right of an array variable's name.
                        So undocumented behavier that might be useful.
                        Dale

                        Comment


                        • #13
                          Does #DEBUG ERROR ON and #DEBUG DISPLAY ON do anything to help?
                          Yes. PowerBASIC will set the ERR variable if there is an out of bounds error with arrays so you can test it using IF ERR THEN ....
                          Sounds like a good idea in this instance until you find the error.
                          https://www.tesla.com/roadster

                          Comment


                          • #14
                            Keith,

                            Right about 6 digits, but I think you forgot about the "float" in floating point.
                            Code:
                            #compile exe
                            #dim all
                            
                            function pbmain () as long
                              local X_Test as single
                              X_Test = 0.00000012345678
                              print "0.00000012345678 becomes ";X_Test
                              X_Test = 12345678000000
                              print "12345678000000 becomes ";X_Test
                              waitkey$
                            end function
                            Cheers,
                            Dale

                            Comment


                            • #15
                              Stuart you are spot on. Revenue_Percentage_Prof_Diff_Factor was indeed being divided by zero.

                              I do have an error trap at the start of the function but it doesn't pick it up.

                              Just read up "Numeric errors such as Divide-by-zero, Overflow and Underflow are not trapped"

                              At the start of the code I have

                              Code:
                              #COMPILE EXE
                              #DIM ALL
                              #DEBUG ERROR ON
                              #OPTIMIZE CODE ON
                              #OPTIMIZE SPEED
                              #DEBUG DISPLAY ON
                              #TOOLS ON
                              Although the error is not trapped I'm surprised that additional legal operations are ignored.

                              Comment


                              • #16
                                There are things to learn here

                                I am not being critical - well I am, but I do it myself!

                                The presumption that the compiler is wrong is usually wrong. Especially in a well established and well written compiler such as PB. Especially for a 'normal' operation.

                                When you assume the bug is in the compiler, if you are not careful, it blinds you to the possibility of having made the error yourself. And you do not look at the right place.

                                I repeat that one of the most important things I learned early on as a professional programmer is the confidence to stand up and say in front of everybody 'There is a bug in my program. i have made a mistake. I will find my mistake. It is not the compiler'

                                This is a good character builder

                                And I repeat lesson one of debugging 'If you cannot see the fault - look somewhere else'

                                [But relax Steve - we have all done it!]
                                [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                                Kerry Farmer

                                Comment

                                Working...
                                X