RosettaCodeData/Task/Ultra-useful-primes/FutureBasic/ultra-useful-primes.basic
2026-04-30 12:34:36 -04:00

108 lines
2.3 KiB
Text

// ------------------------------------------------------------
// Ultra-useful primes sequence
// Using FutureBasic 7.0.36
// November 2025, R.W
//
// a(n) = smallest odd k such that 2^(2^n) - k
// is (probable) prime
// ------------------------------------------------------------
include "gmp.incl"
_kPrimeReps = 25
_kMaxExp = 32767
int gN
CFTimeInterval t
// Abbreviate big numeric string
local fn AbbrevCFNumber( s as CFStringRef, head as int, tail as int ) as CFStringRef
if s = 0 then RETURN @""
int n : n = len(s)
if n <= head + tail then RETURN s
CFStringRef a, b
a = left (s, head)
b = right(s, tail)
CFStringRef out = @""
out = concat ( a , @"...", b)
end fn = out
// Compute a(n), print n, a(n), and abbreviated prime
void local fn ComputeAndPrint( n as Int )
UInt32 mexp : mexp = 1
int i
for i = 1 to n
mexp = mexp << 1
next
// Guard against overflow in 32-bit exp; once it explodes, bail
if mexp > _kMaxExp
print using "##";n;" ** exp beyond ";_kMaxExp
RETURN
end if
mpz_t p
mpz_init(p)
// p = 2^mexp - 1
fn mpz_ui_pow_ui(p, 2, mexp)
fn mpz_sub_ui(p, p, 1)
long k : k = 1
while fn mpz_probab_prime_p(p, _kPrimeReps) = 0
k = k + 2
fn mpz_sub_ui(p, p, 2)
wend
// Convert to string and abbreviate
CFStringRef pStr = fn mpz_cf2(p)
CFStringRef shortStr = fn AbbrevCFNumber(pStr, 36, 36)
print using "##";n; using "######"; k;" "; shortStr
mpz_clear(p)
end fn
// Get next 5 sequence
local fn next5
t = fn CACurrentMediaTime
for int n = gN to gN+4
fn ComputeAndPrint(n)
next
printf @"\nElapsed time time: %.3f secs\n", (fn CACurrentMediaTime-t)
gN = n
end fn
void local fn DoDialog( ev as long, tag as long, wnd as long, obj as CFTypeRef )
select ( ev )
case _btnClick
select ( tag )
case 2
fn next5
end select
end select
end fn
on dialog fn DoDialog
// Main
window 1, @"Ultra-useful primes sequence", (60,60,640,520)
button 2,YES,,@"Next 5",(10,20,100,20),,,1
on dialog fn doDialog
print @" n"; @"\t"; @"a(n)"; @"\t"; @"prime"
print string$(60, "-")
// start the clock
t = fn CACurrentMediaTime
int n
for n = 1 to 10
fn ComputeAndPrint(n)
next
gN = n
printf @"\nElapsed time time: %.3f secs\n", (fn CACurrentMediaTime-t)
HandleEvents