Arbitrary Precision Calculator w/ Library ● SmileBASIC Source

Register
💀

# Arbitrary Precision Calculator w/ Library

Submitted
Updated
Author
amihart
Public Key
J3A3EEK6
Min. Compat.
All
Version
0.7
Rating
Description This is an arbitrary precision calculator, essentially meaning it always gives exact numbers. It only supports positive integers. The program APCALC supports order of operations, as shown in the screenshot. This program comes with both APCALC and APCALC.LIB. APCALC is an actual calculator that supports order of operations. The .LIB is a library you can import into your code and then do math using arbitrary precision. The calculator supports these operators:
2. - (subtraction)
3. * (multiplication)
4. / (division)
5. % (modulus)
6. ^ (exponentiation)
7. & (bitwise AND)
8. | (bitwise OR)
9. ! (bitwise XOR)
10. < (left shift)
11. > (right shift)
Converting between decimal strings and APCALC variables is rather slow so some operations in the actual calculator can seem like they're taking forever but they're actually really quick, it's just atm the conversion is really slow, so like even though addition is really fast, 1000000000000...000000+1 might be slow because it has to convert that decimal string to an APCALC variable, do the math, then back again to show you the results. I will hopefully figure out a way to speed up this conversion process in the future. Update 1: - Slightly better performance. - Automatic removal of trailing zeros. - New added "_SAVE" and "_LOAD" function which compresses your files into 32-bit integer arrays. - Added "_GCD" function to find the greatest common divisor between two numbers (Euclid's algorithm). - Added "_RND" function for generating a random APCALC variable.
Instructions Run APCALC to use the calculator. Open DEV_EXAMPLE if you want to see how to use the library.
Categories
Keywords
20 Comment(s) Simeon Scholar Received for knowing a great deal about programming topics Achievements Amazing Page Hidden Achievements Drawing I like to draw! Hobbies Brilliant! I created this too a while back, but mine was too slow Could you give us some insight on the benchmarks; how many milliseconds each operation takes? amihart It depends on how long the number you're operating on and whether or not you're using the new or old 3DS as well as the specific operation you're doing. Here's a graph of the multiplication function. The X axis is number of 9s being multiplied. Such that 5 on the X axis is 99999*99999. The Y axis is the number of milliseconds it takes to execute. As you can see, it gets slower the larger the number gets. It hits 100 milliseconds at about 55, so if you multiply `9999999999999999999999999999999999999999999999999999999*9999999999999999999999999999999999999999999999999999999` it will take about 100 milliseconds to calculate on the new 3DS. I haven't done anything on the old 3DS but I tend to find that the difference in speed is about 3.4, meaning it would likely take about 340 milliseconds on the old to calculate that. It's obviously not completely linear as well. I did multiplication because it's sort of in the middle, it's slower than addition but faster than division, and I did all 9s because that produces the largest result, so your result is a lot larger than the two numbers being multiplied. On the new 3DS, it takes about 3.5 seconds to evaluate this statement: `9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999*9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999` (this is one-thousand 9s multiplied by another one-thousand 9s) I'd guess 12 seconds on the original 3DS. Simeon Scholar Received for knowing a great deal about programming topics Achievements Amazing Page Hidden Achievements Drawing I like to draw! Hobbies Oh wow! That is impressive I just ran the same test on mine 1000 nines multiplied by 1000 nines Takes 7.2 seconds Yours is almost twice as fast, which is impressive because I spent a long time making mine as efficient as possible amihart On the original 3DS or the new 3DS? If it's the original 3DS it's actually a little faster. And how did you do yours? I did mine using strings and treating them as base-65536 numbers. Simeon Scholar Received for knowing a great deal about programming topics Achievements Amazing Page Hidden Achievements Drawing I like to draw! Hobbies No mine is on a New 3DS too, so yours is faster How I did mine, treated each number as a base-10 number string, I do have overhead on mine because I put a lot of focus on positive and negatives. I then used my library to recreate java.util.random. Successfully made java's pseudo random work on SmileBASIC, so that I could create a slime chunck finder (Minecraft) After the slime chunk finder was done, it was extremely laggy java.util.random took roughly 120 milliseconds per number So this project came to an immediate end There must be a way to do this without strings I couldn't figure it out amihart Ah, base-10 number strings are going to be slower because you have to iterate through more characters. If I wanted to do something with the number 150000000000000000000000000000000000000000000000, in your library you'd have to iterate through all 49 characters while my library would only have to iterate through 10 characters. And yours also seems to work with negative numbers which may also be a reason, as you mentioned. The reason mine is positive integer only is really because I just built it so I could play around with RSA encryption, which this is sufficient for it. 12Me21 Admin Syntax Highlighter Received for creating the code syntax highlighter on SBS Night Person I like the quiet night and sleep late. Express Yourself Second Year My account is over 2 years old Website Your _CMP function can be replaced with ```COMMON DEF _CMP(A\$,B\$) IF A\$>B\$ THEN RETURN 1 IF A\$<B\$ THEN RETURN -1 RETURN 0 END```(And you can just compare strings directly most of the time; for example _CMP\$(T\$,CHR\$(0))!=0 can be T\$!=CHR\$(0)) You can also replace: ```STRING\$=STRING\$+... -> PUSH STRING\$,... STRING\$=...+STRING\$ -> UNSHIFT STRING\$,... MID\$(STRING\$,POSITION,1) -> STRING\$[POSITION] ``` Loading the library can be done with `USE "PRG1:APCALC.LIB"` Y_ack Head Admin Why does code in comments wrap. 12Me21 Admin Syntax Highlighter Received for creating the code syntax highlighter on SBS Night Person I like the quiet night and sleep late. Express Yourself Second Year My account is over 2 years old Website because your screen is too small amihart Thanks. I'll implement this and upload a new version later today. 12Me21 Admin Syntax Highlighter Received for creating the code syntax highlighter on SBS Night Person I like the quiet night and sleep late. Express Yourself Second Year My account is over 2 years old Website You also might want to create OUT\$ with the correct size to begin with, if this is known (for example, with bitwise OR) ```COMMON DEF _OR(A\$,B\$) VAR L%=MAX(LEN(A\$),LEN(B\$)) VAR OUT\$=" "*L% VAR I% FOR I%=0 TO L%-1 OUT\$[I%]=CHR\$(ASC(A\$[I%]) OR ASC(B\$[I%])) NEXT RETURN OUT\$ END ``` This is faster because you don't need too resize the strings, but it will not remove extra CHR\$(0)s , so you'll either have to do that separately, or only use this method in operations where the output length is known. amihart Alright. The _CMP statement didn't seem to work, it seems to think "000" > "0" which obviously isn't true, and if I were to build in a check for this it might slow it down even further, I'd still need to iterate through the whole thing to remove excess 0s. 12Me21 Admin Syntax Highlighter Received for creating the code syntax highlighter on SBS Night Person I like the quiet night and sleep late. Express Yourself Second Year My account is over 2 years old Website I don't think any of your functions add leading 0s, though it's probably a good idea to check for them in your compare function unless you're completely sure. amihart Functions the produce a smaller number can have leading zeros. e.g. in base-65536 the number 65536 is [1][0] so if I do 65536-1 I get [0][65535]. 12Me21 Admin Syntax Highlighter Received for creating the code syntax highlighter on SBS Night Person I like the quiet night and sleep late. Express Yourself Second Year My account is over 2 years old Website You should probably make it not add leading 0s, to avoid memory leaks. Once a number has leading zeros they probably won't go away. amihart I can add a method to allow the user to optionally trim down numbers to remove trailing zeros. I don't want to force it to trim the number every time because of unnecessary slowdown. The memory space essentially expands to the max size of what is needed to do your operations. amihart nvm I'll just add a trim method and include it at the end of the methods that might leave trailing zeros. Hopefully it won't effect performance too much. 12Me21 Admin Syntax Highlighter Received for creating the code syntax highlighter on SBS Night Person I like the quiet night and sleep late. Express Yourself Second Year My account is over 2 years old Website If you really want it to be as fast as possible you could use arrays instead, but it wouldn't be as convenient since you'd always have to DIM them . randomous Owner Robot Hidden Easter Eggs Second Year My account is over 2 years old Website Drawing I like to draw! Hobbies But as long as you pre-create the APCALC variables and only use those variables in all future math, it's fast right? amihart It's pretty fast for most operations, yeah. The APCALC variables are stored in strings, and if you have a string of just 10 characters long, you can hold any number between 0 and 1,461,501,637,330,902,918,203,684,832,716,283,019,655,932,542,976. And obviously it doesn't take very long to operate on only 10 characters. The larger the number, the longer the string, and the slower it'll take to operate on it, but you can get to pretty massive numbers without noticing any slowdown.