QBasic, 156 characters
INPUT n#
?n#;"=";
f=2
1c=0
WHILE n#/f=INT(n#/f)
n#=n#/f
c=c+1
WEND
IF c THEN?f;
IF c>1THEN?"^";c;
IF c*(n#>1)THEN?"*";
f=f+1
IF f*f<=n#GOTO 1
IF n#>1THEN?n#
When run at Archive.org, this takes about 2½ minutes to finish for an input of 4294967291, the largest prime in the specified range.
Ungolfed, with some remarks
This is the version I used to get the timing information:
CLS
INPUT num#
PRINT num#; "=";
factor = 2
startTime# = TIMER
DO
count = 0
WHILE num# / factor = INT(num# / factor)
num# = num# / factor
count = count + 1
WEND
IF count > 0 THEN PRINT factor;
IF count > 1 THEN PRINT "^"; count;
IF count > 0 AND num# > 1 THEN PRINT "*";
factor = factor + 1
LOOP WHILE factor * factor <= num#
IF n# > 1 THEN PRINT n# ELSE PRINT
time# = TIMER - startTime#
PRINT "Search took"; INT(time# / 60); "minutes and";
PRINT INT(time# mod 60); "seconds"
The program uses the standard approach of trial division of each factor between \$2\$ and \$\sqrt n\$. It prints a *
after each successful factor if the remaining \$n\$ is still greater than 1. If the factor becomes greater than \$\sqrt n\$ while \$n > 1\$, then \$n\$ is prime and we output it after exiting the loop.
A few extra bytes had to be spent to cope with very large numbers:
QBasic's numbers are either single- or double-precision floating point under the hood, although it casts to integers for certain calculations. Integers greater than \$2^{24}\$ are not guaranteed to be accurately represented in single-precision floating point, so we have to use double-precision for \$n\$ (thus the double-precision sigil on the variable num#
). However, since we're only checking factors up to \$\sqrt n < 2^{16}\$, we can use the default single precision for factor
.
At first, I had WHILE num# MOD factor = 0
for the inner loop. This worked until I tried numbers close to \$2^{32}\$, at which point it said "Overflow." It seems that the MOD
operator casts its operands to integers--specifically, 32-bit signed integers. A value of \$2^{32}-1\$ can fit in a 32-bit unsigned integer, but not a signed one. So MOD
wasn't going to work. Neither was my usual golf trick of checking divisibility with a/b=a\b
, since the int-div operator \
also casts to integers. Fortunately, I could still use floating point division and then truncate explicitly with the INT
function (which seemingly does not cast to integer--??).
Given the issues with single- vs. double-precision, I assumed that squaring factor
(single-precision) before comparing it with num#
(double) wasn't going to work. But surprisingly, it did. My best guess after some experimentation is that if there's a double-precision value anywhere in an expression, QBasic casts all of the values to double before computing anything. This contrasts with C, for example, where implicit casting only occurs between the operands of a single operator.