Announcement

Collapse
No announcement yet.

PRINT Bug with CSNG?

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

  • PRINT Bug with CSNG?

    Consider the following code snippets...
    1. PRINT "1/3 = "; 1.0 / 3.0 ' output = "1/3 = .3333333"
    2. PRINT "1/3 = "; 1.0# / 3.0# ' output = "1/3 = .333333333333333"
    3. PRINT "1/3 = "; CSNG(1.0# / 3.0#) ' output = "1/3 = .333333343267441"
    4. PRINT "1/3 = "; CSNG(1.0 / 3.0) ' output = "1/3 = .333333343267441"
    1 and 2 make sense to me (single and double precision). 3 and 4 do not make sense to me. It looks to me like the compiler is converting the single or double precision number to a single precision number using the CSNG function and then printing the result as a double precision number. The interesting thing is that if I define a single precision variable and do the conversion first and then print the result, I get what I expect (single precision PRINT results).

    Am I missing something or is this an issue with the compiler?

    Thanks in advance for your help.

  • #2
    Whenever you deal with displaying floating point numbers you are probably best off in the long run to use the USING$() or FORMAT$() functions to control the number of decimal digits shown.

    Otherwise, you are at the mercy of what the compiler thinks you mean... and the compiler obviously thinks different things depending on how you form your expression.
    Last edited by Michael Mattias; 27 May 2008, 09:00 AM.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Scott
      Welome to Basic (I note from another post your experience is C dialects) this may be a bug but if so the most common type that has been around in Basic since earliest implementations.
      One of Basics unique features has always been that the compilers automatically convert all numeric types such that the math operation can occur. In 30 years have never found a compiler that always could understand what I wanted 100% of the the time.
      Take the example 1.3# * 2&, some compilers would give the answer 2.6 others 2 (usually depending if they are LR or RL compilers)
      PB in all cases you show has given the single its correct IIEE specification ie 6 decimal places correct.
      You were given the "magic fix" by Guy and myself for a simple conversion of this clients program, ie do a global replacement of all "AS DOUBLE" to "AS SINGLE" or as nothing and use Guys line and your client will have a modern PBCC program that gives the results he/she are used to

      Comment


      • #4
        Gents,

        Thanks for your replies. I think it is a bug in the compiler. Here is my workaround that works fine.

        FUNCTION CSINGLE(BYVAL AA!) AS SINGLE
        FUNCTION = AA!
        END FUNCTION

        FUNCTION PBMAIN () AS LONG
        PRINT "1/3 = "; CSINGLE(1.0#/3.0#)
        END FUNCTION

        The output is
        1/3 = .3333333

        This shows me that the compiler properly interprets my function CSINGLE() as returning a single precision floating point number but does not properly interpret CSNG() as noted above.

        I am satisfied using this workaround as it makes the program run as the client expects, however, it would be great to have the PB team comment and confirm as a bug or help me to understand the PRINT CSNG() behavior.

        Comment


        • #5
          >PRINT "1/3 = "; CSNG(1.0 / 3.0)

          In this statement, "CSNG(1.0/3.0)" - what you want to PRINT - is an expression, not a print format. I'm sure what the compiler is doing is "1.0 /3.0" using whatever default it uses for untyped numeric literals (which I believe is EXT? It's in the help file somewhere) and then after that converting the intermediate result to a single.

          This is not a bug at all. It is, however, a terrific demo of what happens when using floating point data and not carefully specifying literals and output formats.

          If you still think this is a bug, you should email your source code and a description of the problem to [email protected], as this board is not an official communcations channel to PowerBASIC Inc.

          MCM
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            It looks to me like the compiler is converting the single or double precision number to a single precision number using the CSNG function and then printing the result as a double precision number.
            I would say that is exactly what is happening and it's not a bug.

            The result of 1.0# / 3.0# is a DOUBLE, CSNG converts that to a SINGLE, it is then converted back to a DOUBLE and printed.

            As you noticed, if you use a SINGLE variable it prints "1/3 = .3333333".

            The moral of the story: always use declared variables.
            Last edited by Greg Lyon; 28 May 2008, 02:30 PM.

            Comment


            • #7
              Ever since the 386, the 86 family of processors have had problems with scientific type notation of numbers, that is to say many digits.

              With scientific calculations there are better processors and better compilers
              (Fortran comes to mind) albeit they may not be as fast in some respects as the x86 architecture just because of intel and others devotion to speeding
              things up.
              Client Writeup for the CPA

              buffs.proboards2.com

              Links Page

              Comment


              • #8
                Ever since the 386, the 86 family of processors have had problems with scientific type notation of numbers
                No they haven't. The chips do what the chips do; it's up to software to do something with that behavior.

                Think about it: people market "many digit" arithmetic packages which run on the same chips, don't they?
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Originally posted by Fred Buffington View Post
                  Ever since the 386, the 86 family of processors have had problems with scientific type notation of numbers, that is to say many digits.
                  Sorry, but that's absolutely incorrect. The Intel CPU is absolutely accurate to the IEEE standard. It's up to the programmer to learn and understand the nature of approximations which may be necessary in virtually any floating point operation.

                  If you expect floats to always work like your recollections of pencil/paper, you will be disappointed. If you follow industry-standard "best practices", floats will work very well for you.

                  Best regards,

                  Bob Zale
                  PowerBASIC Inc.

                  Comment


                  • #10
                    >If you expect floats to always work like your recollections of pencil/paper..

                    Use this very problem: 1.0/3.0

                    Call me when the division is complete (no remainder).
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      0.3333333'

                      Comment


                      • #12
                        Originally posted by Michael Mattias View Post
                        Use this very problem: 1.0/3.0
                        Call me when the division is complete (no remainder).
                        That's the reason that rational numbers were 'invented' .
                        Rational numbers consist of a numerator and a nominator, as in A/B, where A and B are integers (of arbitrary length).
                        So the result of your division example would simply be (and remain) (1,3) (= 1/3).

                        Rational numbers have the advantage that there are never rounding errors with addition, subtraction, multiplication and division ! So basically never, unless the maximum size of the integer numerator or denominator is exceeded.

                        The arbitrary precision math library I am currently developing has rationals as one of 4 available arbitrary precision numerical data types.

                        Kind regards
                        Eddy

                        Comment

                        Working...
                        X