QB64.org Forum
Active Forums => QB64 Discussion => Topic started by: PROFESPAN@frontier.com on April 09, 2022, 10:57:41 am
-
Below please see a QB64 program that evokes mathematical errors in some DOUBLE PRECISION numbers. In particular, PRINT 1.D-40 produces 1.D-41, which is ten times smaller than the correct answer 1.D-40.
Here is the test program:
Data 1D-40#,1E-40
Read x#, y!
Print .0000000000000000000000000000000000000001#: Rem: 1D-41 is the result
Print 1# / 10000000000000000000000000000000000000000#: Rem: 1D-41 is the result
Print x#
Print 10000000000000000000000000000000000000000#: Rem: 1D+40 is the result
Print 1# / 10000#: Rem: .0001 is the result
Print .0001#: Rem: .0001 is the result
Print 1D0 / 1.D40: Rem: 1D-41 is the result
Print 1D-40: Rem: 1D-41 is the result
Print 1D0 / 1D20: Rem: 1D-21 is the result
Print 1D-20: Rem: 1D-21 is the result
Print 1D0 / 1D19: Rem: 1D-19 is the result
Print 1D-19: Rem: 1D-19 is the result
Print 0.0000000000000000000000000000000000000001: Rem: 1D-41 is the result
Print 1 / 10000000000000000000000000000000000000000.: Rem: 1D-41 is the result
Print y!: Rem: 9.999946E-41 is the result
Print 10000000000000000000000000000000000000000.: Rem: 1D+40 is the result
Print 1 / 10000: Rem: .0001 is the result
Print .0001: Rem: .0001 is the result
Print 1E0 / 1E40: Rem: 9.999946E-41 is the result
Print 1E-40: Rem: 9.999946E-41 is the result
Print 1E0 / 1E20: Rem: .0001 is the result
Print 1E-20: Rem: .0001 is the result
Print 1E0 / 1E19: Rem: 1D-19 is the result
Print 1E-19: Rem: 1D-19 is the result
End
Note that 1D-19 prints correctly but 1D-20 does not. SINGLE precision seems to work ok.
It may make a difference if the decimal point is included in some of the numbers, for instance, 1.D-40 instead of 1.D-40. However, the errors may be worse.
Please fix this problem.
Sincerely yours,
Dr. Edwin L. Kerr, Retired NASA physicist and engineer with 60 years of computer programming experience.
-
Welcome to forum Edwin,
Double only has 8 bytes precision about 15 decimals give or take and according to others Print has a mind of it's own.
https://wiki.qb64.org/wiki/Variable_Types
jack might have something for you and those that need precision math. I can give you some slow String math routines with arbitrary precision for add, subtr and mult, 100 decimal precision for division oh I have Sqr now too if I recall.
Original author of QB64 left and those that maintain QB64 complain of code mess. QB64 really a hobbiest language for Retro gamers.
-
hello Dr. Edwin and bplus
as you noted the QB64 print functions are buggy in some cases, until they get fixed you could use the crt's printf function
let me modify an example, then I'll post
not the best example, but you can modify the code to your needs
l
= snprintf
(s
, Len(s
), frmt
, x
) strf = s
-
Welcome Dr. Kerr,
Having coded a space flight simulator for a table top role playing game, that bears NO resemblance to a real guidance system, I can attest to the fact that precision has its limits in QB64. Particularly with respect to print formatting. As Bplus says, I've occasionally had to resort to formatting functions and other such expedients to get where I want to go.
That said, QB64 is a modern upgrade of QBasic/QB4.5 and adds gobs of functionality, previously undreamed of for us QBasic users. I just wouldn't get on a space ship that used it...yet.
-
another example
l
= snprintf
(s
, Len(s
), frmt
, x
) strf = s
the qbs_str function in libqb.cpp which is called by the print statement is a bit complex, at least for the non-C-expert, it could be simplified a lot if you want give up certain formatting rules imposed by trying to match the output of QB45
-
Please fix this problem.
Its open source on Github, have at it.
Though if I were planning on landing a rover on Pluto I would probably go with an assembly language that matches the processors used in its onboard computer(s). Then you would have much more control over how you want floating point numbers handled. But if you just want to play around with simulating such events and learning how to overcome, sidestep or work around certain limitations then Welcome To BASIC.
-
Dr. Kerr designed a laser instrument for measuring the height of volcanoes and the depth of valleys and rifts on Mars. The finished instrument, the Mars Global Surveyor, is still orbiting Mars. It was the first successful use of a laser beyond the orbit of the Moon. Thanks to the instrument our contour maps of Mars are better than the ones we have of the Earth. Another instrument like the first mapped the Asteroid Eros and reposes on it. A third instrument is aboard the MESSENGER mission to Mercury. The Japan Aerospace Exploration Agency put a similar instrument on the Hayabusa space probe, which recently returned rock samples from the Asteroid Itokawa.
N. A. S. A. awarded Dr. Kerr a prize for his design of a telescope (shown at right) adapted to receive laser communications from space probes going to Jupiter, Uranus, and Neptune, into the Kuiper Belt as far as 35 times the distance to Pluto, or beyond. The telescope will be one of the largest in the world.
That's pretty cool.
-
Cobalt, the problem is that for some values the printed result is off by a factor of 10, it's not just a minor flaw
to fix the qbs *qbs_str(double value) is complicated by the fact that QB64 want to match the output of qb45 and the code is rather complex due to that
I mentioned this before that _Floats are converted to double then passed to qbs_str(double value)
qbs *qbs_str(long double value){
//not fully implemented
return qbs_str((double)value);
}
I propose a simple alternative
qbs *qbs_str(long double value){
//not fully implemented
static qbs *tqbs;
static int32 l, i;
static char c;
tqbs=qbs_new(32,1);
l=__mingw_sprintf((char*)&qbs_str_buffer,"% .18Lg",value);
for (i=0;i<l;i++) {
c=qbs_str_buffer[i];
if(c==101) c=70;
tqbs->chr[i]=c;}
tqbs->chr[l]=0;
return tqbs;
}
example
d = 1D17
f = 1F17
d = d * 10#
f = f * 10##
output
Double 1D+18
_Float 1F+18
------------
Double 1D+19
_Float 1F+19
------------
Double 1D+20
_Float 1F+20
------------
Double 1D+21
_Float 1F+21
------------
Double 1D+22
_Float 1F+22
------------
Double 1D+22
_Float 1F+23
------------
Double 1D+24
_Float 1F+24
------------
Double 1D+24
_Float 1F+25
------------
Double 1D+25
_Float 1F+26
------------
Double 1D+26
_Float 1F+27
------------
Double 1D+28
_Float 1F+28
------------
Double 1D+28
_Float 1F+29
------------
Double 1D+29
_Float 1F+30
------------
Double 1D+30
_Float 1F+31
------------
Double 1D+31
_Float 1F+32
------------
Double 1D+32
_Float 1F+33
------------
Double 1D+33
_Float 1F+34
------------
Double 1D+35
_Float 1F+35
------------
Double 1D+35
_Float 1F+36
------------
Double 9.999999999999998D+36
_Float 1F+37
------------
Double 9.999999999999998D+37
_Float 1F+38
------------
Double 9.999999999999998D+38
_Float 1F+39
------------
Double 9.999999999999998D+39
_Float 1F+40
------------
Double 9.999999999999998D+40
_Float 1F+41
------------