Clean way to write Double into String without the trailing ".0" ?

A

abc

Easy newbie-question here for the experts:

What's a clean way of writing a Double into a String, avoiding
the ".0" at the end ?

The Double.toString() method insists on appending a decimal fraction
".0" no matter what, and I only want the fractions to show up if they
are non-zero.

I found a dirty workaround (see code below), using a regex to remove the
trailing ".0", but there has to be a prettier way to do this.

....
String s = Double.toString(x);
s = s.replaceAll((String)"\\.0$", "");
....

TIA
 
K

Knute Johnson

Easy newbie-question here for the experts:

What's a clean way of writing a Double into a String, avoiding
the ".0" at the end ?

The Double.toString() method insists on appending a decimal fraction
".0" no matter what, and I only want the fractions to show up if they
are non-zero.

I found a dirty workaround (see code below), using a regex to remove the
trailing ".0", but there has to be a prettier way to do this.

....
String s = Double.toString(x);
s = s.replaceAll((String)"\\.0$", "");
....

TIA

public class test {
public static void main(String[] args) throws Exception {
Double d = new Double(666.234);
System.out.println(String.format("%.0f",d.doubleValue()));
}
}

C:\Documents and Settings\Knute Johnson>java test
666
 
E

Eric Sosman

Easy newbie-question here for the experts:

What's a clean way of writing a Double into a String, avoiding
the ".0" at the end ?

The Double.toString() method insists on appending a decimal fraction
".0" no matter what, and I only want the fractions to show up if they
are non-zero.

I found a dirty workaround (see code below), using a regex to remove the
trailing ".0", but there has to be a prettier way to do this.

....
String s = Double.toString(x);
s = s.replaceAll((String)"\\.0$", "");

Perhaps it shows my age, but something inside me cringes
at the notion of wheeling out the regular expression cannon to
kill so simple a canary.

s = s.substring(s.indexOf('.'));

"Cleaner" -- and certainly more flexible -- alternatives are
to use a java.text.DecimalFormat or a java.util.Formatter instead
of toString().
 
J

Jeff Higgins

abc said:
Easy newbie-question here for the experts:

What's a clean way of writing a Double into a String, avoiding
the ".0" at the end ?

The Double.toString() method insists on appending a decimal fraction
".0" no matter what, and I only want the fractions to show up if they
are non-zero.

I found a dirty workaround (see code below), using a regex to remove the
trailing ".0", but there has to be a prettier way to do this.

....
String s = Double.toString(x);
s = s.replaceAll((String)"\\.0$", "");
....

TIA
String s = Double.toString(x).replaceAll((String)"\\.0$", "");
 
A

abc

Eric said:
Perhaps it shows my age, but something inside me cringes
at the notion of wheeling out the regular expression cannon to
kill so simple a canary.

Same here, hence my question.
s = s.substring(s.indexOf('.'));

Wouldn't this get rid of the decimal fraction part completely, whether
it's non-zero or not? That's not what I want.

"Cleaner" -- and certainly more flexible -- alternatives are
to use a java.text.DecimalFormat or a java.util.Formatter instead
of toString().

Thanks, I'll read up on those.
 
M

markspace

abc said:
Aren't int and long both integer types though?
Wouldn't this cause the decimal fraction be lost?


Yes. Just to be clear to everyone, he wants to remove the trailing
zeros only if they are all zero. If he has a component after the
decimal place with digits besides 0, he wants it printed.

Sorry but I don't see a solution to your problem. I think you will have
to hack it. Regex looks good to me.
 
E

Eric Sosman

Same here, hence my question.

Wouldn't this get rid of the decimal fraction part completely, whether
it's non-zero or not? That's not what I want.

Actually, I botched the substring() call, and ought
to have written

s = s.substring(0, s.indexOf('.'));

.... and yes, this version would snip the decimal point and
everything that follows. That's what I thought you wanted,
but on re-reading your message I see that you only wanted to
jettison a literal ".0" and keep other fractional parts.
(I've obviously been hitting the eggnog too hard today ...).

In penance, here's another possibility:

if (s.endsWith(".0"))
s = s.substring(s.length() - 2);
Thanks, I'll read up on those.

Probably the best course, since they'll also spare you
from unpleasantnesses like "10.333333333333334". Note that
PrintStream has convenience methods for using Formatter.
 
J

Jeff Higgins

markspace said:
Yes. Just to be clear to everyone, he wants to remove the trailing
zeros only if they are all zero. If he has a component after the
decimal place with digits besides 0, he wants it printed.

Sorry but I don't see a solution to your problem. I think you will have
to hack it. Regex looks good to me.


I don't either that why I replied as I did.

The .0 is acting as an indicator that the represented number is a
floating-point approximation, removing it hides that indication.

Good, bad, dirty, clean, pretty, plain?
Depends upon agreement between producer, consumer.
 
T

Tom McGlynn

Easy newbie-question here for the experts:

What's a clean way of writing a Double into a String, avoiding
the ".0" at the end ?

The Double.toString() method insists on appending a decimal fraction
".0" no matter what, and I only want the fractions to show up if they
are non-zero.

I found a dirty workaround (see code below), using a regex to remove the
trailing ".0", but there has to be a prettier way to do this.

....
String s = Double.toString(x);
s = s.replaceAll((String)"\\.0$", "");
....

TIA

Personally I think what you've done (absent the redundant cast that
others have mentioned) is a perfectly fine way to do what you want. I
think the code very clearly reflects your requirement.

If you are concerned with efficiency or feel that you don't want to
unleash the 'big guns' of regular expressions, then perhaps you could
put your conditional code before you do the conversion.
E.g. something like:

double MAX_TEST = Integer.MAX_VALUE;
...
String s;
int ix = (int) x; // If the (int) conversion is slow, perhaps
Math.floor(x)
// and only create the int when you need it.
if (Math.abs(x) <= MAX_TEST && (x == ix)) {
s = Integer.toString(ix);
} else {
s = Double.toString(x);
}

I suspect that's more efficient, but I'd check if it mattered. This
only handles numbers between -2^31 - 2^31. You can get bigger if you
use longs instead. If you have very big numbers then you need to
worry about exponent notation too. The real defect here is that it
that compared to your original the intent is much less clear.

Regards,
Tom McGlynn
 
J

Jeff Higgins

Tom said:
If you have very big numbers then you need to worry about exponent notation too. The real defect here is that it
Good catch.
OK Double.valueOf(1000000.0).toString().replaceAll("\\.0$", "")
OOPS Double.valueOf(10000000.0).toString().replaceAll("\\.0$", "")
 
K

Knute Johnson

Yes. Just to be clear to everyone, he wants to remove the trailing zeros
only if they are all zero. If he has a component after the decimal place
with digits besides 0, he wants it printed.

OK, then I like this :).

public class test {
public static void main(String[] args) throws Exception {
Double d = new Double(666);
String s = d.toString();
System.out.println(s);

if (s.endsWith(".0"))
s = s.substring(0,s.length()-2);

System.out.println(s);
}
}
 
K

Kevin McMurtrie

Easy newbie-question here for the experts:

What's a clean way of writing a Double into a String, avoiding
the ".0" at the end ?

The Double.toString() method insists on appending a decimal fraction
".0" no matter what, and I only want the fractions to show up if they
are non-zero.

I found a dirty workaround (see code below), using a regex to remove the
trailing ".0", but there has to be a prettier way to do this.

....
String s = Double.toString(x);
s = s.replaceAll((String)"\\.0$", "");
....

TIA

private static final NumberFormat s_fmt=
new DecimalFormat("0.################");

....
final String str;
synchronized (s_fmt)
{
str= s_fmt.format(d);
}
....
 
L

Lew

Kevin said:
private static final NumberFormat s_fmt=
new DecimalFormat("0.################");

...
final String str;
synchronized (s_fmt)
{
str= s_fmt.format(d);
}
...

I thought so, too, but that pattern doesn't eliminate the decimal point when
the fractional part is zero.
 
L

Lew

Kevin said:
private static final NumberFormat s_fmt=
new DecimalFormat("0.################");

...
final String str;
synchronized (s_fmt)
{
str= s_fmt.format(d);
}
...

In a heavily multi-threaded, high-throughput environment that synchronized
static formatter could be quite a choke point. If that turns out to be the
case, one could use

str = new DecimalFormat("0.################").format(d);

Naturally you'd want to elevate the string to a final constant either way.

This assumes you don't mind keeping the decimal point when the fractional part
is zero.

Java has come a long way in optimization of uncontended locks, but contended
ones are inherently a bitch. It can be astonishing how much time is spent
waiting to acquire a lock in a contentious scenario, to the severe detriment
of throughput. On projects where I've seen such things actually measured, a
highly-contended synchronization lock has been the major throughput killer,
beating even database I/O despite the latter being very poorly handled in some
cases. And that was with Java 5.

If the formatter is lightly touched, then the lock won't be such an issue.
 
K

Kevin McMurtrie

[QUOTE="Lew said:
private static final NumberFormat s_fmt=
new DecimalFormat("0.################");

...
final String str;
synchronized (s_fmt)
{
str= s_fmt.format(d);
}
...

I thought so, too, but that pattern doesn't eliminate the decimal point when
the fractional part is zero.[/QUOTE]

When I run it, 10.0d returns "10" and 10.1d returns "10.1".
 
A

abc

Tom said:
Personally I think what you've done (absent the redundant cast that
others have mentioned) is a perfectly fine way to do what you want.

OK, thanks.

There has been a couple of mentions of the "redundant cast".

If what you mean by this is the (String)"\\.0$" I had to put it in
because I found I get an error message there if I remove the (String)
part like this:

s = s.replaceAll("\\.0$", ""); // error, with (String) removed
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top