# Cutting unnecessary zeroes in float numbers

Hello. I have function, which shows a float number with comma instead of dot. But if i use this function on integer it shows float number. Here is the function

\begin{sagesilent}
def numprint(x):
x = round(x, ndigits=3)
x = latex(x)
x = str(x)
x = x.replace('.', ',\!').replace('\\times','\, \ldotp')
x = sage.misc.latex.LatexExpr(x)
return x
\end{sage}
\newcommand{\sagedot}[1]{\sagestr{numprint(RDF(#1))}}


So, when i use \sagedot{3} it shows 3.0 instead of 3. Help me to improve it. Thanks and sorry for dumb english and question :D

edit retag close merge delete

Sort by ยป oldest newest most voted

You could just check that

type(x) == float


Or, instead of round, you could use python's string formatter.

"{:.5g}".format(x)


will format x using 5 digits of precision (including before and after the decimal separator), removing trailing zeroes and the decimal dot for integers. Not exactly equivalent to your code, but maybe it will be good enough for your use.

If you have a locale configured for French/Italian/whatever notation

"{:.5n}".format(x)


will automatically put a comma instead of a dot for you.

more

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.

more

That was really dumb.

\begin{sagesilent}
def numprint(x):
x = round(x, ndigits=3)
x = latex(x)
x = str(x)
x = x.replace('.', ',\!').replace('\\times','\, \ldotp')
x = x.rstrip('0').rstrip(',\!') if ',\!' in x else x
x = sage.misc.latex.LatexExpr(x)
return x
\end{sagesilent}
\newcommand{\sagedot}[1]{\sagestr{numprint(RDF(#1))}}


Maybe this solution is dumb too, but it works :D

more