Author Topic: Maths accuracy  (Read 8451 times)

0 Members and 1 Guest are viewing this topic.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Maths accuracy
« Reply #15 on: May 26, 2021, 02:33:44 pm »
OK, it is the 'nature of the beast' as they say.

So if I try to force a decimal place with:

INT(number * 100) / 100     ' or _ROUND, etc.

then am I just reintroducing the same floating point error again when dividing by 100?

It would seem then that PRINT USING is the only answer.

Ir’s not the same floating point error, but a *new* floating point error.  Usually the computer can sort out when to round up/down a few decimal places (or else 1/3 * 3 would forever be 0.999999999999 instead of 1), but sometimes it still screws up.  As you mention: it’s simply the nature of the beast.

Only solution I can offer in this case is just to up your precision level as much as possible, and hope it fixes the issue.  Or write a custom function to convert to string and manually insert the decimal:

FUNCTION ex## (x##)
   ex## = INT(x## * 100)
   temp$ = STR$(ex##)
   temp1$ = LEFT$(temp$, LEN(temp$) - 2) + “.” + RIGHT$(temp$, 2)
   ex## = VAL(temp1$)
END FUNCTION

Floating point math removed — problem removed.

(You may need my routine to remove/convert scientific notation, if your values are too large.  They’re here on the forums if you need them.)
« Last Edit: May 26, 2021, 02:35:32 pm by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline JohnUKresults

  • Newbie
  • Posts: 40
    • View Profile
Re: Maths accuracy
« Reply #16 on: May 26, 2021, 02:37:34 pm »
Thanks all

I just need to 2 decimal points, to take one number from the other and store in a variable (not to print)

I think I have a solution which probably does the job, if a bit untidily

Best wishes to all

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Maths accuracy
« Reply #17 on: May 26, 2021, 02:56:55 pm »
Quote
(You may need my routine to remove/convert scientific notation, if your values are too large.  They’re here on the forums if you need them.)

Yeah I posted the link in reply #7

You know I have same problem with adding machine I made from QB64. It really makes you wonder what's going when the 3rd decimal shows up and all you are doing is adding and substracting up to 2 digit floats.

Well no more, I am taking my own advice from reply #11 and dumping the the bloody dot's.
« Last Edit: May 26, 2021, 03:01:29 pm by bplus »

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: Maths accuracy
« Reply #18 on: May 26, 2021, 02:57:58 pm »
Good, because mine would take some time to convert to QB64.

I noticed that for division, it looks like you do an inverse of the denominator then multiply.

In mine, I create a factor table based on the quotient, and do subtraction instead, carrying over the remainder until I'm subtracting from 0 or I reach the preset decimal places.

Thanks for showing me. I will add it to my programs when needed.





Hey @George McGinn

I have String Math here:
https://www.qb64.org/forum/index.php?topic=2921.msg121886#msg121886

Somewhere in toolbox here:
https://www.qb64.org/forum/index.php?topic=1511.msg107143#msg107143

And my oh Interpreter uses it:
https://www.qb64.org/forum/index.php?topic=3723.msg130797#msg130797

Basic +-*/ and Inverse to get 1 / any Integer to how many ever places you like, default for divide is 100 digits but  mult numerator by inverse of denominator gives that precision at least.

Can work out powers and trig but no one has called for it.
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: Maths accuracy
« Reply #19 on: May 26, 2021, 03:02:18 pm »
I also coded square root and root functions in mine.

I can work just on those and add them to your routines, if anyone needs them.

Hey @George McGinn

Can work out powers and trig but no one has called for it.
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Maths accuracy
« Reply #20 on: May 26, 2021, 03:08:39 pm »
I also coded square root and root functions in mine.

I can work just on those and add them to your routines, if anyone needs them.

If you do root functions that means you did powers for floats? I'd be interested in that.

I found a way to do powers with Sqr(2) and base 2 math but not sure I want to try that with string math.

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: Maths accuracy
« Reply #21 on: May 26, 2021, 08:42:30 pm »
@bplus

Here is the code for the square root and n'th root of a number.  I checked my source, and for the x^y, all I did was perform a loop with the multiplication function. Your code should work the same.

I converted this code from SmartBASIC on the mobile device (allows to code BASIC for iOS apps) which is what the code was originally written for. I had to make some changes to get it to work in QB64, and I verified the results.

Code: QB64: [Select]
  1.  
  2. DECLARE FUNCTION root_2 (A)
  3. DECLARE FUNCTION root_n (A, n)
  4.  
  5. '*** square root function
  6. A = 4503599627370496: r = root_2(A): PRINT "square root of "; A; " equals "; result
  7. A = 125: r = root_2(A): PRINT "square root of "; A; " equals "; result
  8. A = 100: r = root_2(A): PRINT "square root of "; A; " equals "; result
  9.  
  10. '*** n'th root function
  11. A = 100000: n = 6: r = root_n(A, n): PRINT n; "'th root of "; A; " equals "; result
  12. PRINT: PRINT "==================================================================="
  13.  
  14.  
  15. FUNCTION root_2 (A AS DOUBLE)
  16.     x = A / 2: precision = 0.000001: max_iterations = 30
  17.     FOR i = 1 TO max_iterations
  18.         dx = (x - A / x) / 2: x = x - dx
  19.         IF ABS(dx) < precision THEN i = max_iterations
  20.     NEXT i
  21.     result = STR$(x)
  22.  
  23. ' n'th root function
  24. ' n is positive integer (x^(n-1)) by repeated multiplication)
  25. ' n as positive real number requires exponentiation function
  26. '
  27. FUNCTION root_n (A AS DOUBLE, n AS INTEGER)
  28.     x = A / 2: precision = 0.000001: max_iterations = 30
  29.     FOR i = 1 TO max_iterations
  30.         dx = (x - A / x ^ (n - 1)) / n: x = x - dx
  31.         IF ABS(dx) < precision THEN i = max_iterations
  32.     NEXT i
  33.     result = STR$(x)
  34.  

If you do root functions that means you did powers for floats? I'd be interested in that.

I found a way to do powers with Sqr(2) and base 2 math but not sure I want to try that with string math.
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: Maths accuracy
« Reply #22 on: May 26, 2021, 08:51:43 pm »
Speaking of accuracy...

  [ You are not allowed to view this attachment ]  
You're not done when it works, you're done when it's right.

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: Maths accuracy
« Reply #23 on: May 26, 2021, 11:27:42 pm »
@bplus @STxAxTIC

I screwed up the code, my bad. I made changes to that by mistake and didn't change it back (I was fixing the precision issue with square roots).

Change line 34 to be:
Code: [Select]
x = A / 2: precision = 0.001: max_iterations = 100


The value for precision needs to be 0.001 and max_iterations needs to be changed from 30 to 100.

Here is the new program:

Code: Text: [Select]
  1. DIM SHARED result AS STRING
  2. DIM SHARED x AS DOUBLE
  3. DIM SHARED A AS DOUBLE
  4.  
  5. DECLARE FUNCTION root_2 (A)
  6. DECLARE FUNCTION root_n (A, n)
  7.  
  8. '*** square root function
  9. A = 4503599627370496: r = root_2(A): PRINT "square root of "; A; " equals "; result
  10. A = 125: r = root_2(A): PRINT "square root of "; A; " equals "; result
  11. A = 100: r = root_2(A): PRINT "square root of "; A; " equals "; result
  12. PRINT
  13.  
  14. '*** n'th root function
  15. A = 100000: n = 6: r = root_n(A, n): PRINT n; "'th root of "; A; " equals "; result
  16. PRINT: PRINT "==================================================================="
  17. PRINT
  18.  
  19.  
  20. FUNCTION root_2 (A AS DOUBLE)
  21.     x = A / 2: precision = 0.00001: max_iterations = 100
  22.     FOR i = 1 TO max_iterations
  23.         dx = (x - A / x) / 2: x = x - dx
  24.         IF ABS(dx) < precision THEN i = max_iterations
  25.     NEXT i
  26.     result = STR$(x)
  27. END FUNCTION
  28.  
  29. ' n'th root function
  30. ' n is positive integer (x^(n-1)) by repeated multiplication)
  31. ' n as positive real number requires exponentiation function
  32. '
  33. FUNCTION root_n (A AS DOUBLE, n AS INTEGER)
  34.     x = A / 2: precision = 0.001: max_iterations = 100
  35.     FOR i = 1 TO max_iterations
  36.         dx = (x - A / x ^ (n - 1)) / n: x = x - dx
  37.         IF ABS(dx) < precision THEN i = max_iterations
  38.     NEXT i
  39.     result = STR$(x)
  40. END FUNCTION
  41.  


Speaking of accuracy...

  [ You are not allowed to view this attachment ]
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Maths accuracy
« Reply #24 on: May 27, 2021, 12:36:09 am »
@bplus

Here is the code for the square root and n'th root of a number.  I checked my source, and for the x^y, all I did was perform a loop with the multiplication function. Your code should work the same.

I converted this code from SmartBASIC on the mobile device (allows to code BASIC for iOS apps) which is what the code was originally written for. I had to make some changes to get it to work in QB64, and I verified the results.

Code: QB64: [Select]
  1.  
  2. DECLARE FUNCTION root_2 (A)
  3. DECLARE FUNCTION root_n (A, n)
  4.  
  5. '*** square root function
  6. A = 4503599627370496: r = root_2(A): PRINT "square root of "; A; " equals "; result
  7. A = 125: r = root_2(A): PRINT "square root of "; A; " equals "; result
  8. A = 100: r = root_2(A): PRINT "square root of "; A; " equals "; result
  9.  
  10. '*** n'th root function
  11. A = 100000: n = 6: r = root_n(A, n): PRINT n; "'th root of "; A; " equals "; result
  12. PRINT: PRINT "==================================================================="
  13.  
  14.  
  15. FUNCTION root_2 (A AS DOUBLE)
  16.     x = A / 2: precision = 0.000001: max_iterations = 30
  17.     FOR i = 1 TO max_iterations
  18.         dx = (x - A / x) / 2: x = x - dx
  19.         IF ABS(dx) < precision THEN i = max_iterations
  20.     NEXT i
  21.     result = STR$(x)
  22.  
  23. ' n'th root function
  24. ' n is positive integer (x^(n-1)) by repeated multiplication)
  25. ' n as positive real number requires exponentiation function
  26. '
  27. FUNCTION root_n (A AS DOUBLE, n AS INTEGER)
  28.     x = A / 2: precision = 0.000001: max_iterations = 30
  29.     FOR i = 1 TO max_iterations
  30.         dx = (x - A / x ^ (n - 1)) / n: x = x - dx
  31.         IF ABS(dx) < precision THEN i = max_iterations
  32.     NEXT i
  33.     result = STR$(x)
  34.  

Thanks George, I could translate Root_2 for SQR into string math, in fact we were discussing this algo not that long ago.

The algo for Root wont work because it is  for ^ that I need to create a Function. Of course we could do ^ for integers by simple multiplying that many times but that won't help for any real number. So I need a power function done using only +-*/ or inverse functions. I know one way by converting to binary but maybe too Heath Robinson :)

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: Maths accuracy
« Reply #25 on: May 27, 2021, 09:15:33 am »
@bplus, you should be able to create a function for the power of by doing the following:

  • X^Y is passed to the power of function.
  • Values for X and Y are looped to the multiply function/sub, where the loop is performed Y times, multiplying the result of X*X to X.

You should have all the code already written to do this.
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: Maths accuracy
« Reply #26 on: May 27, 2021, 10:44:45 am »
@bplus

NOTE: While you can raise a number to a fractional power (ie: 5^5.5), this code will not do this, as the FOR/NEXT loop must be done as an integer. Once I solve this, I will post the new routine. For now, as long as the power of is an integer, this will work fine.

Here is the code for your program, Math Regulator, to add the power of functionality:

Code for the ELSE IF statements checking for the operator (Note: add ix1 to the DIM AS INTEGER in function mr$:
Code: QB64: [Select]
  1.     DIM adp AS INTEGER, bdp AS INTEGER, dp AS INTEGER, lpop AS INTEGER, ix1 AS INTEGER, cbhold as LONG
  2.  
  3. ...
  4.  
  5.  
  6. '*** Add in Power Of Function
  7.     ELSEIF op$ = "^" THEN
  8.        cbhold = VAL(cb$)
  9.         cb$ = ca$
  10.         FOR ix1 = 1 TO cbhold
  11.             IF ix1 = 1 THEN
  12.                 postOp$ = sgn$ + mult$(ca$, "1")
  13.             ELSE
  14.                 ca$ = postOp$
  15.                 postOp$ = sgn$ + mult$(ca$, cb$)
  16.             END IF
  17.         NEXT ix1

How to test this code:
Code: QB64: [Select]
  1. PRINT "3125 ? "
  2. PRINT mr$("5", "^", "5") ' OK
  3. PRINT "25 ? "
  4. PRINT mr$("5", "^", "2") ' OK

This should work for your power of needs.

George
« Last Edit: May 27, 2021, 10:55:46 am by George McGinn »
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: Maths accuracy
« Reply #27 on: May 27, 2021, 11:12:25 am »
Here is another way you can use 'power of' which I use in the iOS app.

Supposed you wanted to do, say 999999 * 2^53?

The Math Regulator with my changes can do this by using the following code (Put at the top of the MR source):
Code: QB64: [Select]
  1. DIM result$
  2.  
  3.  
  4. ' debug tests
  5.  
  6. '*** Test 999999 * 2^53
  7. result$ = mr$("2", "^", "53")
  8. result$ = mr$("999999", "*", result$)
  9. PRINT "The result of 999999 * 2^53 = "; result$

The results should be: 9,007,190,247,541,737,259,008
« Last Edit: May 27, 2021, 11:13:50 am by George McGinn »
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Maths accuracy
« Reply #28 on: May 27, 2021, 12:03:10 pm »
Hmm...

Like I said a ^ b where b is integer, I get that though god help us if that integer is huge ;-))

But if b were float?

What if I mult b by 10 until it is all integer? mult a (b  * 10 ^ Integer times) then what? divide by some log of 10 Integer times? Yeah, nah... ;-))

1.2 ^ 3.5 = 1.2 ^ (35/10) does this get us closer?



Offline jack

  • Seasoned Forum Regular
  • Posts: 408
    • View Profile
Re: Maths accuracy
« Reply #29 on: May 27, 2021, 12:15:02 pm »
for integer powers you can do something like this
Code: QB64: [Select]
  1.     'take x to an integer power
  2.     Dim As _Integer64 z, y
  3.     Dim As Integer n
  4.     y = x
  5.     n = Abs(e)
  6.     z = 1
  7.     While n > 0
  8.         While (n Mod 2) = 0 ' while n is even
  9.             n = n \ 2
  10.             y = y * y
  11.         Wend
  12.         n = n - 1
  13.         z = y * z
  14.     Wend
  15.     ipow = z
  16.  
« Last Edit: May 27, 2021, 12:24:08 pm by jack »