At the beginning of your function, add a line to test if x
is integer. Optionally, add a test of how large this integer is if you still want to put large integers in scientific notation.
Optionally, you can also test whether x
is a floating-point number equal to zero, in which case you might not want to put it in scientific notation.
Then, you can reduce the number of digits by taking x.n(digits=4)
(this will also turn an integer into a floating-point number, which you may want to do for large integers).
You can then apply the method str
with the option no_sci=False
to make sure to get a scientific notation regardless of the size of x
. The method also has an option skip_zeroes
.
Learn more about this method by reading the documentation:
x = 1.2
x.str?
Combining these tricks, your function could look like this:
def numprint(x):
if type(x) == sage.rings.integer.Integer or type(x) == int:
if abs(x) < 1000: return sage.misc.latex.LatexExpr(x)
if x == 0.: return LatexExpr('0.')
s = x.n(digits=4).str(no_sci=False).split('e')
s = s[0].replace('.', r',\!') + r' \,\ldotp 10^{' + s[1] + '}'
return sage.misc.latex.LatexExpr(s)
I would suggest to check carefully if the output is what you hoped for each in a wide variety of inputs.
z = dict()
z[1] = [0, 1, 100, 1000, 10000, 100000, 10000000000000000000]
z[2] = [12, 123, 1234, 12345, 1234567890, 12345678901234567890]
z[3] = [0., 1., 100., 1000., 10000., 100000., 10000000000000000000.]
z[4] = [12., 123., 1234., 12345., 1234567890., 1234567890123456.]
z[5] = [0.00012, 0.12, 1.2, 1.23, 1.234, 1.23456, 1.2345678]
z[6] = [0.00012345678, 1.2345678, 12.345678, 1234.5678, 1234567.8]
z[7] = [1.2345e-2, 1.2345e-1, 1.2345e0, 1.2345e1, 1.2345e3, 1.2345e5]
for a in z:
print '----- test', a, '-----'
for x in z[a]:
print '%30s%30s'%(x,numprint(x))
print ''
Having a wide range of different inputs to test is good when you are adjusting your function. Add special cases as needed.