DescriptionThis 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:

+ (addition)

- (subtraction)

* (multiplication)

/ (division)

% (modulus)

^ (exponentiation)

& (bitwise AND)

| (bitwise OR)

! (bitwise XOR)

< (left shift)

> (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. InstructionsRun APCALC to use the calculator.
Open DEV_EXAMPLE if you want to see how to use the library.

20 Comment(s)SimeonScholarReceived for knowing a great deal about programming topicsAchievementsAmazing PageHiddenAchievementsDrawingI like to draw!HobbiesBrilliant! 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?amihartIt 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.SimeonScholarReceived for knowing a great deal about programming topicsAchievementsAmazing PageHiddenAchievementsDrawingI like to draw!HobbiesOh 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 possibleamihartOn 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.SimeonScholarReceived for knowing a great deal about programming topicsAchievementsAmazing PageHiddenAchievementsDrawingI like to draw!HobbiesNo 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 outamihartAh, 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.12Me21AdminSyntax HighlighterReceived for creating the code syntax highlighter on SBSOSP Contest 2 WinnerI won the second SmileBASIC Source OSP Contest!Programming ContestSecond YearMy account is over 2 years oldWebsiteYour _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"LumageHead AdminWhy does code in comments wrap.12Me21AdminSyntax HighlighterReceived for creating the code syntax highlighter on SBSOSP Contest 2 WinnerI won the second SmileBASIC Source OSP Contest!Programming ContestSecond YearMy account is over 2 years oldWebsitebecause your screen is too smallamihartThanks. I'll implement this and upload a new version later today.12Me21AdminSyntax HighlighterReceived for creating the code syntax highlighter on SBSOSP Contest 2 WinnerI won the second SmileBASIC Source OSP Contest!Programming ContestSecond YearMy account is over 2 years oldWebsiteYou 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.amihartAlright. 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.12Me21AdminSyntax HighlighterReceived for creating the code syntax highlighter on SBSOSP Contest 2 WinnerI won the second SmileBASIC Source OSP Contest!Programming ContestSecond YearMy account is over 2 years oldWebsiteI 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.amihartFunctions 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].12Me21AdminSyntax HighlighterReceived for creating the code syntax highlighter on SBSOSP Contest 2 WinnerI won the second SmileBASIC Source OSP Contest!Programming ContestSecond YearMy account is over 2 years oldWebsiteYou should probably make it not add leading 0s, to avoid memory leaks. Once a number has leading zeros they probably won't go away.amihartI 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.amihartnvm 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. 12Me21AdminSyntax HighlighterReceived for creating the code syntax highlighter on SBSOSP Contest 2 WinnerI won the second SmileBASIC Source OSP Contest!Programming ContestSecond YearMy account is over 2 years oldWebsiteIf 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 .randomousOwnerRobotHiddenEaster EggsSecond YearMy account is over 2 years oldWebsiteDrawingI like to draw!HobbiesBut as long as you pre-create the APCALC variables and only use those variables in all future math, it's fast right? amihartIt'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.

`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.`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`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"`

`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