OpenVMS
Notes: Fun with FloatsMenu
Food-for-thought. I have been
rereading technical books on DFT-FFT (Discreet Fourier Transform - Fast Fourier
Transform) and most contain example programs written in BASIC (probably since
they are readable by most people). About half of the books
amusingly contain algebra directly coded into BASIC without any regard to the
short comings of computer data types. For example, the following example
contains a FOR-NEXT loop based upon floats like so:
FOR I = 0 TO 2*PI STEP PI/8I'm certain everyone reading this already knows the number-of-loops will change based upon how 2*PI and PI/8 are represented internally. Surprisingly, the VMS BASIC version of the program works properly when variables are changed from DOUBLE to XFLOAT but this could be just a fluke.
Obviously the author should have used a FOR-NEXT loop based upon integers which would manipulate some fraction of PI (unless it was his desire to keep his examples very uncomplicated)
1 REM ============================================================= 2 REM title : DFT1_0.bas (fig 1.3 on Page 8) 3 REM book : Understanding the FFT (c) Anders E. Zonst 4 REM language: GWBASIC for Windows PC 5 REM ============================================================= 10 REM *** DFT1.0 - GENERATE SQUARE WAVE *** 12 INPUT "NUMBER OF TERMS";N 20 PI = 3.14159265358# 30 FOR I = 0 TO 2*PI STEP PI/8 32 Y=0 40 FOR J=1 TO N STEP 2: Y=Y+SIN(J*I)/J: NEXT 50 PRINT Y 60 NEXT I 70 END
10 %title "dft1_0"
declare string constant k_program = "dft1_0"
!=============================================================
! title : DFT1_0.bas (fig 1.3 on Page 8)
! book : Understanding the FFT (c) Anders E. Zonst
! language : GWBASIC for Windows PC
!=============================================================
!10 REM *** DFT1.0 - GENERATE SQUARE WAVE ***
!12 INPUT "NUMBER OF TERMS";N
!20 PI = 3.14159265358#
!30 FOR I = 0 TO 2*PI STEP PI/8
!32 Y=0
!40 FOR J=1 TO N STEP 2: Y=Y+SIN(J*I)/J: NEXT
!50 PRINT Y
!60 NEXT I
!70 END
!=============================================================
! language : HP BASIC for OpenVMS
! port : Neil Rieck
! notes : change lexical %hack to refine results
!-------------------------------------------------------------
! SINGLE ( 32-bit) .29 * 10^-38 to 1.7 * 10^38 6 digits
! DOUBLE ( 64-bit) .29 * 10^-38 to 1.7 * 10^38 16 digits
! GFLOAT ( 64-bit) .56 * 10^-308 to .90 * 10^308 15 digits
! SFLOAT ( 32-bit) 1.18 * 10^-38 to 3.40 * 10^38 6 digits
! TFLOAT ( 64-bit) 2.23 * 10^-308 to 1.80 * 10^308 15 digits
! XFLOAT (128-bit) 6.48 * 10^-4966 to 1.19 * 10^4932 33 digits
!=============================================================
option type=explicit ! required by HP BASIC for OpenVMS
option angle=radians ! be sure of trig units
%let %hack=2%
%if %hack=0% %then
option size= (real double, integer long)
declare double i, j, y, n, z
print "-i-real type: double"
%end %if
%if %hack=1% %then
option size= (real tfloat, integer long)
declare tfloat i, j, y, n, z
print "-i-real type: tfloat"
%end %if
%if %hack=2% %then
option size= (real xfloat, integer long)
declare xfloat i, j, y, n, z
print "-i-real type: xfloat"
%end %if
11 margin #0, 132
13 print "-i-program: "+ k_program +" (generate square wave)"
print "display float precision"
print "======================="
print " 1234567890123456789012345678901234"
print "pi (ref) = 3.14159265358979323846264338327950288419716939937510"
print using "pi = ##.##################################";pi
print using "pi*2 = ##.##################################";pi*2.0
print using "pi/8 = ##.##################################";pi/8.0
print using "sin(1.0) = ##.##################################";sin(1.0)
print using "sin(pi) = ##.##################################";sin(pi)
19 input "NUMBER OF TERMS";n
20 z = 0
25 print "Line Y 1234567890123456789012345678901234 I 1234567890123456789012345678901234"
30 for i = 0 to 2*PI step PI/8
32 y = 0
40 for j=1 to n step 2 \ y=y+sin(j*i)/j \ next j
50 print using "#### ##.##################################";z;y;
51 print using " ##.##################################";i
55 z = z + 1
60 next i
70 end
$ run DFT1_0
-i-real type: double (supposed to be 16 digits of precision
-i-program: dft1_0 (generate square wave)
display float precision
=======================
1234567890123456789012345678901234
pi (ref) = 3.14159265358979323846264338327950288419716939937510 (yellow indicates 16 digits)
pi = 3.1415926535897900000000000000000000 (bold indicates 15 digits of precision)
pi*2 = 6.2831853071795900000000000000000000 (bold indicates 15 digits of precision)
pi/8 = 0.3926990816987240000000000000000000 (bold indicates 15 digits of precision)
sin(1.0) = 0.8414709848078970000000000000000000 (bold indicates 15 digits of precision)
sin(pi) = 0.0000000000000001224646799147350000 (bold indicates 15 digits of precision)
NUMBER OF TERMS? 1000
Line Y 1234567890123456789012345678901234 I 1234567890123456789012345678901234
0 0.0000000000000000000000000000000000 0.0000000000000000000000000000000000
1 0.7867047098266320000000000000000000 0.3926990816987240000000000000000000
2 0.7846910587375420000000000000000000 0.7853981633974480000000000000000000
3 0.7859393587706950000000000000000000 1.1780972450961700000000000000000000
4 0.7848981638974470000000000000000000 1.5707963267949000000000000000000000 (red indicates diff from TFLOAT)
5 0.7859393587706950000000000000000000 1.9634954084936200000000000000000000
6 0.7846910587375420000000000000000000 2.3561944901923400000000000000000000
7 0.7867047098266320000000000000000000 2.7488935718910700000000000000000000
8 0.0000000000000602504127728754000000 3.1415926535897900000000000000000000
9 -0.7867047098266310000000000000000000 3.5342917352885200000000000000000000
10 -0.7846910587375420000000000000000000 3.9269908169872400000000000000000000
11 -0.7859393587706940000000000000000000 4.3196898986859700000000000000000000
12 -0.7848981638974470000000000000000000 4.7123889803846900000000000000000000
13 -0.7859393587706930000000000000000000 5.1050880620834200000000000000000000
14 -0.7846910587375440000000000000000000 5.4977871437821400000000000000000000
15 -0.7867047098266310000000000000000000 5.8904862254808600000000000000000000 <<<--- oops, loop ended early
$
$ run DFT1_0
-i-real type: tfloat (15 digits of precision)
-i-program: dft1_0 (generate square wave)
display float precision
=======================
1234567890123456789012345678901234
pi (ref) = 3.14159265358979323846264338327950288419716939937510 (yellow indicates 15 digits)
pi = 3.1415926535897900000000000000000000 (bold indicates 15 digits of precision)
pi*2 = 6.2831853071795900000000000000000000 (bold indicates 15 digits of precision)
pi/8 = 0.3926990816987240000000000000000000 (bold indicates 15 digits of precision)
sin(1.0) = 0.8414709848078970000000000000000000 (bold indicates 15 digits of precision)
sin(pi) = 0.0000000000000001224646799147350000 (bold indicates 15 digits of precision)
NUMBER OF TERMS? 1000
Line Y 1234567890123456789012345678901234 I 1234567890123456789012345678901234
0 0.0000000000000000000000000000000000 0.0000000000000000000000000000000000
1 0.7867047098266320000000000000000000 0.3926990816987240000000000000000000
2 0.7846910587375420000000000000000000 0.7853981633974480000000000000000000
3 0.7859393587706950000000000000000000 1.1780972450961700000000000000000000
4 0.7848981638974460000000000000000000 1.5707963267949000000000000000000000 (red indicates diff from DOUBLE)
5 0.7859393587706950000000000000000000 1.9634954084936200000000000000000000
6 0.7846910587375420000000000000000000 2.3561944901923400000000000000000000
7 0.7867047098266310000000000000000000 2.7488935718910700000000000000000000
8 0.0000000000000617440257325753000000 3.1415926535897900000000000000000000
9 -0.7867047098266310000000000000000000 3.5342917352885200000000000000000000
10 -0.7846910587375420000000000000000000 3.9269908169872400000000000000000000
11 -0.7859393587706940000000000000000000 4.3196898986859700000000000000000000
12 -0.7848981638974460000000000000000000 4.7123889803846900000000000000000000
13 -0.7859393587706940000000000000000000 5.1050880620834100000000000000000000
14 -0.7846910587375410000000000000000000 5.4977871437821400000000000000000000
15 -0.7867047098266350000000000000000000 5.8904862254808600000000000000000000 <<<--- oops, loop ended early
$
$ run DFT1_0
-i-real type: xfloat (33 digits of precision)
-i-program: dft1_0 (generate square wave)
display float precision
=======================
1234567890123456789012345678901234
pi (ref) = 3.14159265358979323846264338327950288419716939937510 (yellow indicates 33 digits)
pi = 3.1415926535897932384626433832795000 (bold indicates 33 digits of precision)
pi*2 = 6.2831853071795864769252867665590000 (bold indicates 33 digits of precision)
pi/8 = 0.3926990816987241548078304229099380 (bold indicates 33 digits of precision)
sin(1.0) = 0.8414709848078965066525023216302990 (bold indicates 33 digits of precision)
sin(pi) = 0.0000000000000000000000000000000009 (???)
NUMBER OF TERMS? 1000
Line Y 1234567890123456789012345678901234 I 1234567890123456789012345678901234
0 0.0000000000000000000000000000000000 0.0000000000000000000000000000000000
1 0.7867047098266324129536091420549900 0.3926990816987241548078304229099380
2 0.7846910587375418025179337058983590 0.7853981633974483096156608458198760
3 0.7859393587706949526402299139422830 1.1780972450961724644234912687298100
4 0.7848981638974458096461601533451350 1.5707963267948966192313216916397500
5 0.7859393587706949526402299139422840 1.9634954084936207740391521145496900
6 0.7846910587375418025179337058983610 2.3561944901923449288469825374596300
7 0.7867047098266324129536091420549900 2.7488935718910690836548129603695600
8 0.0000000000000000000000000000002319 3.1415926535897932384626433832795000
9 -0.7867047098266324129536091420549900 3.5342917352885173932704738061894400
10 -0.7846910587375418025179337058983620 3.9269908169872415480783042290993800
11 -0.7859393587706949526402299139422840 4.3196898986859657028861346520093200
12 -0.7848981638974458096461601533451350 4.7123889803846898576939650749192500
13 -0.7859393587706949526402299139422820 5.1050880620834140125017954978291900
14 -0.7846910587375418025179337058983460 5.4977871437821381673096259207391300
15 -0.7867047098266324129536091420549890 5.8904862254808623221174563436490700
16 -0.0000000000000000000000000000012410 6.2831853071795864769252867665590000 <<<--- better
$
10 %title "dft1_0_alt"
declare string constant k_program = "dft1_0_alt"
!=============================================================
! title : DFT1_0.bas (fig 1.3 on Page 8)
! book : Understanding the FFT (c) Anders E. Zonst
! language : GWBASIC for Windows PC
!=============================================================
!10 REM *** DFT1.0 - GENERATE SQUARE WAVE ***
!12 INPUT "NUMBER OF TERMS";N
!20 PI = 3.14159265358#
!30 FOR I = 0 TO 2*PI STEP PI/8
!32 Y=0
!40 FOR J=1 TO N STEP 2: Y=Y+SIN(J*I)/J: NEXT
!50 PRINT Y
!60 NEXT I
!70 END
!=============================================================
! language : HP BASIC for OpenVMS
! port : Neil Rieck
! notes : change lexical %hack to refine results
!-------------------------------------------------------------
! SINGLE ( 32-bit) .29 * 10^-38 to 1.7 * 10^38 6 digits
! DOUBLE ( 64-bit) .29 * 10^-38 to 1.7 * 10^38 16 digits
! GFLOAT ( 64-bit) .56 * 10^-308 to .90 * 10^308 15 digits
! SFLOAT ( 32-bit) 1.18 * 10^-38 to 3.40 * 10^38 6 digits
! TFLOAT ( 64-bit) 2.23 * 10^-308 to 1.80 * 10^308 15 digits
! XFLOAT (128-bit) 6.48 * 10^-4966 to 1.19 * 10^4932 33 digits
!=============================================================
option type=explicit ! required by HP BASIC for OpenVMS
option angle=radians ! be sure of trig units
%let %hack=2%
%if %hack=0% %then
option size= (real double, integer long)
declare double i, j, y, n, z
print "-i-real type: double"
%end %if
%if %hack=1% %then
option size= (real tfloat, integer long)
declare tfloat i, j, y, n, z
print "-i-real type: tfloat"
%end %if
%if %hack=2% %then
option size= (real xfloat, integer long)
declare xfloat i, j, y, n, z
print "-i-real type: xfloat"
%end %if
11 margin #0, 132
13 print "-i-program: "+ k_program +" (generate square wave)"
print "display float precision"
print "======================="
print " 1234567890123456789012345678901234"
print "pi (ref) = 3.14159265358979323846264338327950288419716939937510"
print using "pi = ##.##################################";pi
print using "pi*2 = ##.##################################";pi*2.0
print using "pi/8 = ##.##################################";pi/8.0
print using "sin(1.0) = ##.##################################";sin(1.0)
print using "sin(pi) = ##.##################################";sin(pi)
19 input "NUMBER OF TERMS";n
25 print "Line Y 1234567890123456789012345678901234 I 1234567890123456789012345678901234"
30 for z = 0 to 16
31 i = z * pi / 8
32 y = 0
40 for j=1 to n step 2 \ y=y+sin(j*i)/j \ next j
50 print using "#### ##.##################################";z;y;
51 print using " ##.##################################";i
60 next z
70 end
$ run DFT1_0_alt
-i-real type: xfloat
-i-program: dft1_0_alt (generate square wave)
display float precision
=======================
1234567890123456789012345678901234
pi (ref) = 3.14159265358979323846264338327950288419716939937510
pi = 3.1415926535897932384626433832795000
pi*2 = 6.2831853071795864769252867665590000
pi/8 = 0.3926990816987241548078304229099380
sin(1.0) = 0.8414709848078965066525023216302990
sin(pi) = 0.0000000000000000000000000000000009
NUMBER OF TERMS? 1000
Line Y 1234567890123456789012345678901234 I 1234567890123456789012345678901234
0 0.0000000000000000000000000000000000 0.0000000000000000000000000000000000
1 0.7867047098266324129536091420549900 0.3926990816987241548078304229099380
2 0.7846910587375418025179337058983590 0.7853981633974483096156608458198760
3 0.7859393587706949526402299139422830 1.1780972450961724644234912687298100
4 0.7848981638974458096461601533451350 1.5707963267948966192313216916397500
5 0.7859393587706949526402299139422840 1.9634954084936207740391521145496900
6 0.7846910587375418025179337058983580 2.3561944901923449288469825374596300
7 0.7867047098266324129536091420549900 2.7488935718910690836548129603695600
8 0.0000000000000000000000000000004285 3.1415926535897932384626433832795000
9 -0.7867047098266324129536091420549910 3.5342917352885173932704738061894400
10 -0.7846910587375418025179337058983580 3.9269908169872415480783042290993800
11 -0.7859393587706949526402299139422840 4.3196898986859657028861346520093200
12 -0.7848981638974458096461601533451350 4.7123889803846898576939650749192500
13 -0.7859393587706949526402299139422820 5.1050880620834140125017954978291900
14 -0.7846910587375418025179337058983460 5.4977871437821381673096259207391300
15 -0.7867047098266324129536091420549910 5.8904862254808623221174563436490700
16 -0.0000000000000000000000000000008570 6.2831853071795864769252867665590000
$
Comparison (160 iterations - ten waves):
line Y from DFT1_0 Y from DFT1_0_alt Comments 0000 0.000000000000000000000000000000000 0.000000000000000000000000000000000 same 0008 0.000000000000000000000000000000232 0.000000000000000000000000000000429 a little higher 0016 -0.000000000000000000000000000001241 -0.000000000000000000000000000000857 a little lower
Comparison (1600 iterations - one hundred waves):
line Y from DFT1_0 Y from DFT1_0_alt Comments 0160 -0.000000000000000000000000000096384 -0.000000000000000000000000000007041 ten time lower
line Y from DFT1_0 Y from DFT1_0_alt Comments 1600 -0.000000000000000000000000009314737 -0.000000000000000000000000000093896 ten times lower
1000 !=====================================================================
! title : Float_Precision_Test.bas
! author : NSR
! created: 2011-01-30
! notes : this test was done with Alpha BASIC V1.6-000 on OpenVMS-8.3
!=====================================================================
option type=explicit !
option size=(real xfloat,integer long) !
declare xfloat xf, &
tfloat tf, &
sfloat sf, &
gfloat gf, &
double d, &
single s, &
string yada$
2000 main:
print "title : Float Precision Test"
print "environment: Alpha BASIC V1.6-000 on OpenVMS-8.3"
yada$ = "0.04444444444444444444444444444444444"
gosub convert_n_display
yada$ = "0.05555555555555555555555555555555555"
gosub convert_n_display
yada$ = "0.01234567891234567891234567891234567"
gosub convert_n_display
goto fini
!
convert_n_display:
xf = real(yada$,XFLOAT)
tf = xf
sf = xf
gf = xf
d = xf
s = xf
print "test data = "; yada$
print using "xfloat = #.###################################";xf
print using "tfloat = #.###################################";tf
print using "sfloat = #.###################################";sf
print using "gfloat = #.###################################";gf
print using "double = #.###################################";d
print using "single = #.###################################";s
print " 0000000001111111111222222222233333"
print " 1234567890123456789012345678901234 precision"
print
return
!
32000 fini:
end
$ run FLOAT_PRECISION_DEMO title : Float Precision Test environment: Alpha BASIC V1.6-000 on OpenVMS-8.3 float precision test - HP BASIC for OpenVMS Alpha test data = 0.04444444444444444444444444444444444 xfloat = 0.04444444444444444444444444444444440 33 digits tfloat = 0.04444444444444440000000000000000000 15 digits sfloat = 0.04444440000000000000000000000000000 6 digits gfloat = 0.04444444444444440000000000000000000 15 digits double = 0.04444444444444440000000000000000000 15 digits (shouldn't this be 16?) single = 0.04444440000000000000000000000000000 6 digits 0000000001111111111222222222233333 1234567890123456789012345678901234 precision test data = 0.05555555555555555555555555555555555 xfloat = 0.05555555555555555555555555555555560 tfloat = 0.05555555555555560000000000000000000 sfloat = 0.05555560000000000000000000000000000 gfloat = 0.05555555555555560000000000000000000 double = 0.05555555555555560000000000000000000 single = 0.05555560000000000000000000000000000 0000000001111111111222222222233333 1234567890123456789012345678901234 precision test data = 0.01234567891234567891234567891234567 xfloat = 0.01234567891234567891234567891234570 tfloat = 0.01234567891234570000000000000000000 sfloat = 0.01234570000000000000000000000000000 gfloat = 0.01234567891234570000000000000000000 double = 0.01234567891234570000000000000000000 single = 0.01234570000000000000000000000000000 0000000001111111111222222222233333 1234567890123456789012345678901234 precision $
Back
to
OpenVMS
Back
to Home