Use Excel-VBA to test values to 10,000 Digits and beyond

Hi.

I have a technique that can test Collatz values up to 10,000 digits long.

It checks a random 10,000 digit seed in about 50 minutes, or a random 1,000 digit seed in about 20 seconds.

Without a few tricks, Excel pretty much insists on jumping into e-notation above 13 digits or so.

If anyone is interested, I will outline my approach to performing arithmetic in excess of 10,000 digits on my home PC.

Thank you.

1 Like

Interested! Do you want to post it?

Sure thing…

Excel/VBA typically limits integers to 12 or 13 digits, and then slips into e-notation. I’ve seen online mentions that the Excel datatype “Currency” can handle numbers up to 15 digits long without loss of precision brought on by e-notation; but that is still far short of my 10,000 digits or more!

I’ve tested my method out to 12,000 places, but my PC started acting a little weird; cursor/mouse/keyboard-freeze and stuff like that. I don’t know where the break-point is, but 10,000 acted up only once when I was running other programs with it; browser sessions for example. When running Excel alone, 10,000 has been stable.

The good news is that Excel/VBA can handle VERY large String (text) variables; something like 2 billion characters, although you’d likely run into other memory issues on a PC with such long strings.

So, to the point…

My code uses a simple looping process to build a seed (or starting) string of random digits of a length I specify, say 10k or anything all the way down to 1. I then apply the Collatz Odd/Even rules to iterate the process to 1. (Maybe someday to I’ll go to infinity and beyond, or into a loop other than 4-2-1.)

The core process works along the length of the seed string (str1) a digit or two at a time, converting the string “integers” into numeric ones, performing the Odd or Even arithmetic, and builds the next iteration string one character at a time.

Here is the core code that builds “str2” or “str3” from “str1,” which then becomes the new str1 for the next pass.

If str1 is even, this divides str1 by 2…

Function doeven() ’ divide by 2
str2 = “”
carry = 0
For a = 1 To Len(str1)
If InStr(“02468”, Mid(str1, a, 1)) > 0 Then ’ currdigit is even
tint = CLng(Mid(str1, a, 1))
If carry = 1 Then
tint = tint + 10
carry = 0
End If
tint = tint / 2
str2 = str2 + CStr(tint)
Else ’ currdigit is odd
tint = CLng(Mid(str1, a, 1))
If carry = 1 Then tint = tint + 10
tint = (tint - 1) / 2
carry = 1
str2 = str2 + CStr(tint)
End If
Next
str1 = str2
End Function

If str1 is odd, this performs the two-step process of (a) multiplying str1 by 3, and then (b) adding 1…

Function doodd() ’ times 3 plus 1
str2 = “”
carry = 0
For a = Len(str1) To 1 Step -1
tint = CLng(Mid(str1, a, 1)) * 3 + carry
carry = 0
If tint > 9 Then carry = 1
If tint > 19 Then carry = 2
str2 = Right(CStr(tint), 1) + str2
Next
If carry > 0 Then str2 = CStr(carry) + str2
If Mid(str2, 1, 1) = “0” Then str2 = Mid(str2, 2)
str3 = “”
carry = 0
tint = CLng(Right(str2, 1))
tint = tint + 1
If tint = 10 Then
tint = 0
carry = 1
End If
str3 = CStr(tint)
If Len(str2) > 1 Then
For a = Len(str2) - 1 To 1 Step -1
tint = CLng(Mid(str2, a, 1))
If carry = 1 Then tint = tint + 1
If tint < 10 Then carry = 0
str3 = Right(CStr(tint), 1) + str3
Next
End If
If carry = 1 Then str3 = “1” + str3
str1 = str3
End Function

That’s pretty much the whole program other than a bunch of “Dim” statements, a routine to generate random seeds of a specified length, counters, duration measurement, and output to spreadsheet cells and text file to show results.

Regarding speed… When I first thunk up this approach, I thought it would be very slow due to all the flip-flops from String to Integer to String, but it seems very fast to me in that regard. Also, I’ve done heavy lifting in the past with Java rather than VBA (as in the Eternity II puzzle) when speed was the total issue; AI told me the other day that VBA is as fast (or faster!) as Java with most functions; I don’t believe that for a millisecond!

Follow-up questions/comments are of course welcomed! If you want it, and if I can, I will send you my full exact .xlsm file (which is still a work in progress); just let me know how! At this time, I am altering the code for various reasons before running; I am in the process of putting those “controls” onto an Excel form with a “Go” button – making an easy GUI. :slight_smile:

That’s great! String arithmetic … wonder if you could shorten the strings by using base 16 (hex) or base 90.

Interesting thought, mathkook. I’ll noodle on that for a while and see if something starts to percolate. Or maybe convert to Base 2 – binary. Here a a binary story for you…

My first “eureka” moment with string arithmetic happened about 19 years ago. I was working with a friend on a puzzle/prize book called “Secrets of the Alchemist Dar.” As an attack on one of the puzzles in the book, we had the need to increment large binary numbers over and over. I wrote VB code to (1) convert binary strings to decimal, then (2) add 1 to the decimal values, then (3) convert the result back to binary.

VB had built-in functions to convert bin-to-dec and vice versa, but they were super-slow.

So I performed the arithmetic on the binary strings manually, working from right to left. 0+0=0; 0+1=1; 1+1=0 carry 1. It was almost like an analog car odometer, but binary.

My place-by-place “rolling of the binary odometer” was thousands of times faster than converting bin to dec, adding 1, converting dec back to bin.

My process here of doing Collatz 3x+1 or x/2 on decimal strings, char by char (rather than decimal integer math) was a close cousin to my binary odometer trick. And again, direct math in Excel is limited to 13 digits, while the string approach reaches easily (and quickly) into thousands of digits.

1 Like