Announcement

Collapse
No announcement yet.

Newbie questions

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

  • Arthur Gomide
    replied
    Strickley in answer to question -
    Hello Dale,
    Now I'm confused ...I didn't do a question. I just put a code for calculating the ATAN2 function. The complete code is on line 1910. I also know that the PB ATN function returns its value in extended-precision and the ATAN2 function will use this precision only if it is in the interest of the programmer. Typically, implementations of the ATAN2 function takes some space, I'd say about 10 lines of code - This version fit in just one line! But yes, to run in extended precision are necessary the changes that you indicated.
    Anyway my thanks!
    Arthur.
    Code:
        LOCAL R1, SE, SN, X AS EXT  'single
    
    120 R1=5.72957795130823209e+01##    '57.29578!


    Leave a comment:


  • Dale Yarker
    replied
    Strickley in answer to question -
    For extended-precision values, make the necessary changes.
    change - LOCAL R1, SE, SN, X AS SINGLE
    to - LOCAL R1, SE, SN, X AS EXTENDED
    plus change degrees to radians

    (no other checks made for run time errors or compile time errors)

    ((The ATN function in PB is natively extended.))
    Last edited by Dale Yarker; 16 Aug 2016, 10:08 AM.

    Leave a comment:


  • Arthur Gomide
    replied
    My solution to ATAN2, in the 80, when I was using a TRS-80 Model III
    For extended-precision values, make the necessary changes.
    Code:
    120 R1=57.29578!
        '
        ' SE contains delta sin
        ' SN contains delta cos
        ' ATAN2 returns in X
        '
    1910 IF SN=0 THEN X=90-(SE<0)*90 ELSE X=ATN(SE/SN)*R1-(SN<0)*180:IF X<0 THEN X=X+360
    
    Test code:
    Code:
    #COMPILE EXE
    #DIM ALL
    
    FUNCTION PBMAIN () AS LONG
    
        LOCAL R1, SE, SN, X AS SINGLE
    
    120 R1=57.29578!
    1200 SE= 0:SN= 0:GOSUB 1910: PRINT "For SE= 0:SN= 0: ATAN2 should be   0" X 'prints 0
    1210 SE= 0:SN= 1:GOSUB 1910: PRINT "For SE= 0:SN= 1: ATAN2 should be   0" X 'prints 0
    1220 SE= 1:SN= 1:GOSUB 1910: PRINT "For SE= 1:SN= 1: ATAN2 should be  45" X 'prints 45
    1230 SE= 1:SN= 0:GOSUB 1910: PRINT "For SE= 1:SN= 0: ATAN2 should be  90" X 'prints 90
    1240 SE= 1:SN=-1:GOSUB 1910: PRINT "For SE= 1:SN=-1: ATAN2 should be 135" X 'prints 135
    1250 SE= 0:SN=-1:GOSUB 1910: PRINT "For SE= 0:SN=-1: ATAN2 should be 180" X 'prints 180
    1260 SE=-1:SN=-1:GOSUB 1910: PRINT "For SE=-1:SN=-1: ATAN2 should be 225" X 'prints 225
    1270 SE=-1:SN= 0:GOSUB 1910: PRINT "For SE=-1:SN= 0: ATAN2 should be 270" X 'prints 270
    1280 SE=-1:SN= 1:GOSUB 1910: PRINT "For SE=-1:SN= 1: ATAN2 should be 315" X 'prints 315
    1290 SE= 0:SN= 1:GOSUB 1910: PRINT "For SE= 0:SN= 1: ATAN2 should be   0" X 'prints 0
         WAITKEY$
         EXIT FUNCTION
    1910 IF SN=0 THEN X=-(SE<>0)*(90-(SE<0)*180) ELSE X=ATN(SE/SN)*R1-(SN<0)*180:IF X<0 THEN X=X+360
    1920 RETURN
    
    END FUNCTION
    
    atan2 test.zip

    Leave a comment:


  • Aldo Vitagliano
    replied
    Thanks Arthur for the interesting link.
    However, the calculator does not support 80 bits Extended precision conversion.

    Leave a comment:


  • Arthur Gomide
    replied
    Francis,

    Use this calculator to see what happens

    IEEE-754 Floating-Point Conversion

    Leave a comment:


  • Francis Reddy
    replied
    Aldo and Robert:

    Thank you both for the informative replies.

    Frank

    Leave a comment:


  • Robert DeBolt
    replied
    First of all, we must acknowledge the fact that digital computers cannot natively represent real numbers such as pi or e. By truncating such numbers to an arbitrary precision, we can only represent a real number in terms of a rational approximation.

    In calculus, the student will see that an irrational number exists only as the limit of the sequence of its rational approximations.


    PowerBASIC compilers have chosen to represent real numbers in terms of the PC's internal representation of single, double and extended-precision approximations.

    Consider an extension to the above program by:
    Code:
    #COMPILE EXE
    #DIM ALL
     
    FUNCTION PBMAIN () AS LONG
    LOCAL a,b,c AS EXT
     
    '-------------------------------------------------------------
    PRINT "'--- Part 1 is the original program"
    PRINT "'    It shows that the ""closest"" precise value of pi"
    PRINT "'    should be 3.14159265358979323##,
    PRINT "'    yet it prints as 3.14159265358979312
    PRINT "'    a difference of 0.00000 00000 00000 11
     
    a=3.1415926535897932384626##
     
    PRINT " 3.1415926535897932384626 = Pi"
    PRINT a "        = Variable set to above, no formal formatting"
     
    PRINT " " + FORMAT$(a,18) + "      = Displayed through FORMAT$(a,18)"
    PRINT STR$(a,18) + "      = Displayed through STR$(a,18)"
     
    PRINT:PRINT
     
    '-------------------------------------------------------------
    PRINT "'--- Part 2 is a modified version of Part 1
    PRINT "'    obtained by trial and error by incrementing
    PRINT "'    3.14159265358979312 by 0.00000 00000 00000 01
    PRINT "'    until the printed version is greater than 3.14159265358979312.
    PRINT "'    This value is 3.14159265358979334
    PRINT "'    a difference of 0.00000 00000 00000 22
     
    b=3.14159265358979333##     ' 18 digits
     
    PRINT " 3.14159265358979311      = Pi"
    PRINT b "        = Variable set to above, no formal formatting"
     
    PRINT " " + FORMAT$(b,18) + "      = Displayed through FORMAT$(b,18)"
    PRINT STR$(b,18) + "      = Displayed through STR$(b,18)"
     
    PRINT:PRINT
     
    '-------------------------------------------------------------
    PRINT "'--- Part 3 is a modified version of Part 1
    PRINT "'    obtained by trial and error by decrementing
    PRINT "'    3.14159265358979312 by 0.00000 00000 00000 01
    PRINT "'    until the printed version is less than 3.14159265358979312.
    PRINT "'    This value is 3.14159265358979279
    PRINT "'    a difference of 0.00000 00000 00000 33
     
    c=3.14159265358979289##     ' 18 digits
     
    PRINT " 3.14159265358979334      = Pi"
    PRINT c "        = Variable set to above, no formal formatting"
     
    PRINT " " + FORMAT$(c,18) + "      = Displayed through FORMAT$(c,18)"
    PRINT STR$(c,18) + "      = Displayed through STR$(c,18)"
     
    WAITKEY$
     
    END FUNCTION
    Code:
    '--- Part 1 is the original program
    '    It shows that the "closest" precise value of pi
    '    should be 3.14159265358979323##,
    '    yet it prints as 3.14159265358979312
    '    a difference of 0.00000 00000 00000 11
     3.1415926535897932384626 = Pi
     3.14159265358979         = Variable set to above, no formal formatting
     3.14159265358979312      = Displayed through FORMAT$(a,18)
     3.14159265358979312      = Displayed through STR$(a,18)
     
    '--- Part 2 is a modified version of Part 1
    '    obtained by trial and error by incrementing
    '    3.14159265358979312 by 0.00000 00000 00000 01
    '    until the printed version is greater than 3.14159265358979312.
    '    This value is 3.14159265358979334
    '    a difference of 0.00000 00000 00000 22
     3.14159265358979311      = Pi
     3.14159265358979         = Variable set to above, no formal formatting
     3.14159265358979312      = Displayed through FORMAT$(b,18)
     3.14159265358979312      = Displayed through STR$(b,18)
     
    '--- Part 3 is a modified version of Part 1
    '    obtained by trial and error by decrementing
    '    3.14159265358979312 by 0.00000 00000 00000 01
    '    until the printed version is less than 3.14159265358979312.
    '    This value is 3.14159265358979279
    '    a difference of 0.00000 00000 00000 33
     3.14159265358979324      = Pi
     3.14159265358979         = Variable set to above, no formal formatting
     3.14159265358979267      = Displayed through FORMAT$(c,18)
     3.14159265358979267      = Displayed through STR$(c,18)
    This program shows that the "true" value of pi is somewhere between 3.14159265358979279 and 3.14159265358979334, but cannot be represented exactly as 3.14159265358979324 in binary code, since floating-point is not represented internally as decimal. This is what we call "floating-point error."

    If you require greater precision than this, I suggest you look at
    Eddy Van Esch's HIME Huge Integer Math and Encryption library.

    Leave a comment:


  • Aldo Vitagliano
    replied
    Actually, the best way of storing Pi in extended precision is doing like this:

    Pi## = 4*ATN(1)

    Because although not more than 18 significant digits can be printed and read, at least 19 significant digits are stored in memory and used in calculations in the 10 bytes extended precision format.

    Want to check it ?
    Code:
    DEFEXT A-Z
    FUNCTION PBMAIN()
       PI=4*ATN(1)  '.......   PI = 3.14159265358979323846....  21 digits
       PRINT STR$(Pi,18) '...output 3.14159265358979324     18 digits printed
       Pidec=PI*10-31
       PRINT STR$(Pidec, 18) '.. outp .415926535897932385 two more digits recovered 
       WAITKEY$
    END FUNCTION
    Regards
    Aldo
    Last edited by Aldo Vitagliano; 5 Dec 2007, 08:21 AM. Reason: comment additions to code

    Leave a comment:


  • Michael Mattias
    replied
    Extended-precision values require 10 bytes of storage each. They have a range of approximately +/- 3.4x10^-4932 to 1.2x10^4932, and offer 18 digits of precision. All 18 digits can be "displayed" using the extended STR$ format (eg, STR$(var##,18)).
    How many digits in "3.1415926535897932384626?"

    How does that number compare to the documented limit for signficant digits for data type EXT?

    Leave a comment:


  • Rodney Hicks
    replied
    Chapter 3, Data Types
    Check under the heading "Numeric Literals". Page 108 in the hard copy.

    Leave a comment:


  • Francis Reddy
    replied
    Michael:

    The only variable is defined as EXT, so I don't see how differences between single, double, and extended precision apply here, unless there are differences in the way over-precise values are handled (which I did not see in the help).

    According to the documentation under single precision, a too-precise value is supposed to be rounded. Altering 3.14...3238 to 3.14...312 doesn't seem to follow that rule, whereas 3.14...324 would. If you're rounding, why change the next to last digit?

    Leave a comment:


  • Michael Mattias
    replied
    Count digits. Compare with documented limits. Your question will answer itself.

    Also refer to the documentation on assigning numeric literals. Ok, so that's really hard to find. Suffice it to say there is a difference between:

    a=3.1415926535897932384626!
    and
    a=3.1415926535897932384626#
    and
    a=3.1415926535897932384626##

    MCM

    Leave a comment:


  • Francis Reddy
    replied
    It's not clear to me why PB/CC 4.04 gives the following results with FORMAT$ and STR$:

    Code:
    3.1415926535897932384626 = Pi
    3.14159265358979         = Variable set to above, no formal formatting
    3.14159265358979312      = Displayed through FORMAT$(a,18)
    3.14159265358979312      = Displayed through STR$(a,18)
    As displayed by FORMAT$ and STR$, shouldn't the last pair of digits be 23 (if truncated) or 24 (if rounded) rather than 12 that's actually displayed?

    Frank

    Code:
    #COMPILE EXE
    #DIM ALL
    
    FUNCTION PBMAIN () AS LONG
    LOCAL a AS EXT
    
    a=3.1415926535897932384626
              
    PRINT " 3.1415926535897932384626 = Pi"
    PRINT a "        = Variable set to above, no formal formatting"
    
    PRINT " " + FORMAT$(a,18) + "      = Displayed through FORMAT$(a,18)"
    PRINT STR$(a,18) + "      = Displayed through STR$(a,18)"
    WAITKEY$
    
    END FUNCTION
    Last edited by Francis Reddy; 4 Dec 2007, 07:49 AM.

    Leave a comment:


  • Francis Reddy
    replied
    Michael:

    I understand your hot buttons, and I'm not trying to do direct Pascal to Basic conversions, just trying to reboot from one, half-forgotten way of doing things to another. I thought I'd start with the math library.

    As for the Assembler, hey, I have an entire math unit, mostly in ASM, that provides many functions that didn't exist in Pascal and don't natively exist in PowerBASIC. If most of the work is done in ASM, and it can be made to work in PB with little fuss, why not? Granted, though, this won't always be possible for me.

    Richard:

    Thanks so much for your responses and code.

    Leave a comment:


  • Richard Angell
    replied
    Maybe something along these lines, mght be simpler ... but hey I put something into similar macro a long time ago and don't use them everyday either. Result is in radians.
    Code:
    MACRO Pi = 3.141592653589793## 
    FUNCTION Atan2 (BYVAL Y AS SINGLE,BYVAL X AS SINGLE)AS SINGLE
      LOCAL v1 AS SINGLE
      LOCAL A1 AS EXTENDED
      LOCAL sy,sx,quadrant AS LONG
      sy  =  SGN(Y)
      sx  =  SGN(X)
      v1 =  Y/X
      A1 =  ATN(v1)
      SELECT CASE sx
          CASE -1
              IF sy = -1 THEN
                  A1 = -pi + A1
              ELSEIF sy = 0 THEN
                  A1 = pi
              ELSEIF sy = 1 THEN
                  A1 = pi + A1
              END IF
          CASE 0
              IF sy = -1 THEN
                  A1 = pi + (pi/2)
              ELSEIF sy = 0 THEN
                  A1 = 0
              ELSEIF sy = 1 THEN
                  A1 = pi/2
              END IF
      END SELECT
      FUNCTION = A1
    END FUNCTION

    Leave a comment:


  • Michael Mattias
    replied
    I was guessing. But I'm sure someone could tweak that suggestion to make it right.

    But of course, you knew I would suggest "something" because this thread hits not one (1), but two (2) of my "hot button don't do that" topics:

    1. Trying to do verb-for-verb, function-for-function ports of software. (In this case, Pascal==> BASIC)

    2. Using assembly language when the compiler provides sufficient intrinsic functions to get the job done... perhaps in this case to replace intrinsic functions not available in the Pascal Compiler.

    That is, converting from one language to another should not be a 'hardware' or 'software' thing so much as it should be a 'wetware' thing. (Wetware= that stuff between your ears).

    MCM

    Leave a comment:


  • Richard Angell
    replied
    Actually, Michael, your formula is not returning the correct angle in the quadrants (radians or angles). The assembler version does. Here's a quick compare to try with coordinate pairs like (45,45),(45,-45),(-45,-45) and (-45,45) or could use the same absolute values for X and Y, e.g. 10,10 with the signs as noted. So we can quickly see the angular displacement from the X axis counter clockwise for 45,135,225,315 degrees in each quadrant. In the assembler version the function handles quadrants correctly observing "The angle depends on the sign of X and Y independently, not just on the sign of the ratio Y/X." and not on the sign of Y either. So it returns the corrected radian value as a posative or negative radian value from 0.

    Code:
    #COMPILE EXE
    #DIM ALL
    MACRO RadiansToDegrees(dpRadians) = (dpRadians*57.29577951308232##)
    
    FUNCTION Atan2 (BYVAL Y AS SINGLE,BYVAL X AS SINGLE)AS SINGLE
      LOCAL v1,A1 AS SINGLE
      LOCAL s AS LONG
      v1 =  Y/X
      A1 =  ATN(v1)
      s  =  SGN(Y)
      FUNCTION = ABS(A1) * s
    END FUNCTION
    
    FUNCTION ArcTan2(BYVAL Y AS SINGLE,BYVAL X AS SINGLE)AS SINGLE
        ! emms
        ! fld Y
        ! fld X
        ! fpatan
        ! fstp Y
        FUNCTION = Y
    END FUNCTION
    
    FUNCTION PBMAIN () AS LONG
        LOCAL y,x,theta AS SINGLE,answer AS STRING
    repeat:
        ? ""
        INPUT "enter the ordinate,abcissa: " ,y,x
        theta = RadiansToDegrees(ArcTan2(y,x))
        IF SGN(theta) = -1  THEN theta = 360 +theta
        ? "ArcTan2 result: "+FORMAT$(ArcTan2(y,x)),theta
        theta = RadiansToDegrees(Atan2(y,x))
        IF SGN(theta) = -1  THEN theta = 360 +theta
        ? "Atan2   result: "+FORMAT$(Atan2(y,x)),theta
        ? ""
        ? "press q to quit or another key to continue ...
        answer$ = WAITKEY$
        IF LCASE$(answer$) <> "q" THEN GOTO repeat
    
    END FUNCTION
    Last edited by Richard Angell; 27 Nov 2007, 10:23 AM. Reason: edits

    Leave a comment:


  • Michael Mattias
    replied
    The FPATAN instruction returns the angle between the X axis and the line from the origin to the point (X,Y), where Y (the ordinate) is ST(1) and X (the abscissa) is ST(0). The angle depends on the sign of X and Y independently, not just on the sign of the ratio Y/X. This is because a point (-X,Y) is in the second quadrant, resulting in an angle between pi/2 and pi, while a point (X,-Y) is in the fourth quadrant, resulting in an angle between 0 and pi/2. A point (-X,-Y) is in the third quadrant, giving an angle between -pi/2 and -pi.
    Code:
    FUNCTION Atan2 (X, Y) 
    
      v1 =  Y/X
      A1 =  ATN(v1) 
      s  =  SGN(Y)
    
      FUNCTION = ABS(A1) * s
    END FUNCTION
    ????

    (May need special handling when Y=0 ???)

    Leave a comment:


  • Richard Angell
    replied
    I've not had asm need for floating point, but based on your code and some posts and your code, might be similar to this:
    Code:
    FUNCTION ArcTan2(BYVAL Y AS SINGLE,BYVAL X AS SINGLE)AS SINGLE
        ! emms             ;no MMX while FP used 
        ! fld Y
        ! fld X
        ! fpatan
        ! fstp Y
        FUNCTION = Y
    END FUNCTION
    Maybe Bob, Hutch, Paul or another FP assembler user can beat this code or point out any error.

    Leave a comment:


  • Francis Reddy
    replied
    Okay, now the trickier stuff. Here's an old Virtual Pascal routine:

    FUNCTION ArcTan2(Y,X: REAL): REAL; ASSEMBLER;
    ASM fld Y
    fld X
    fpatan
    END; { ArcTan2. }

    Can someone show me how this would work in PowerBASIC?

    Thanks for the handholding.

    Frank

    Leave a comment:

Working...
X