Efficient Scientific Notation
ES6, 83 81 bytes
x=>(e=s=>s.replace(/e\+?/,'x10^'),z=e(x.toExponential()),y=e(''+x))[z.length]?z:y
Probably fails for some edge cases where toString
insists on exponential format.
Edit: Saved 2 bytes thanks to @user81655.
Python 3, 346 342 319 302 bytes
L=len;N=str(float(input()))
if N.endswith('.0'):N=N[:-2]
if'e'in N:C,P=N.split('e');N=N.replace('e','x10^')
else:
C=N.strip('.0').replace('.','');F=N.find('.')
if L(C)>1:C=C[0]+'.'+C[1:]
P=((L(N) if F==-1 else F)-1-N.lstrip('0').find(C[0]))
print(min([N,'{0}x10^{1}'.format(C,int(P))],key=L))
Probably horribly golfed, but hey, this is my first try at something like this. It's hard to read, so it must be good.
As far as I'm aware, it should work on every case, even with Python's tendency to automatically convert numbers past whatever threshold into scientific notation (except with that cool and fancy 'e'). I don't remember exactly how I made that be able to return standard form numbers, but it does that.
Perl 6, 96 90 bytes
I feel like this could be shorter, but this is my best for now
{my \s=($_,*×(1>$_??10!!.1)…10>*>=1);min(s[*-1]~"x10^"~(1>$_??1-s!!s-1),$_,by=>&chars)}
usage: Assign this to a variable
Here it is ungolfed a bit with some bad commentary:
my &f = -> $n {
my $a = 1 > $n ?? 10 !! .1; # If $n < 1, we will multiply by 10
# in the sequence below, else by 0.1
my @seq = ($n, * × $a ... 10 > * >= 1); # Sequence starting at $n,
# multiply the previous value by $a
# until we reach a number 1 <= x < 10
# Join the last element in @seq, "x10^", and the length of @seq,
# with an extra subtraction for numbers less than 1.
# this gets us our scientific notation.
my $science = @seq[*-1] ~ "x10^" ~ @seq - (1 > $n ?? @seq*2 !! 1);
min($science, $n, by => &chars) # Uses the &chars function to
# choose a min value and return it.
}