Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

truncate to 2 decimals places 1

Status
Not open for further replies.

lowbk

Technical User
Nov 26, 2001
162
SG
hi, i need advice on truncating a double to a double of 2 decimal places. my method is written as
Code:
	private static double trancate(double x)
	{
		long y=(long)x*100;
		double z= (double)y/100;

		return z;
	}

strangely, the returned result has no decimals. i have tried DecimalFormat but it is returning a STRING instead of a double.
 
Try -
Code:
private static double truncate(double x)
{
    long y=(long)(x*100);
    return (double)y/100;
}

Tim
---------------------------
"Your morbid fear of losing,
destroys the lives you're using." - Ozzy
 
thanks timw, it works. but i don't understand the logic behind. do you mind explaining?
 
Certainly.

As you had it, the
Code:
long y=(long)x*100;

was casting the x to a long before it was multiplied by 100. So you were losing your fractional digits there. Putting brackets around the multiplication forces the cast to be performed on the result of the multiplication, thus preserving the fractional digits you were after.

Tim
---------------------------
"Your morbid fear of losing,
destroys the lives you're using." - Ozzy
 
For big doubles the method will produce garbage, I guess.

Code:
	public BigDoubleRounded ()
	{
		checkDouble (999999999999999999999999999999.999999999);
		checkDouble (0.9090909);
		checkDouble (1234.123456);
		checkDouble (9090909.9090909);
	}

	private void checkDouble (double d)
	{
		System.out.println ("d:\t" + d);
		System.out.println ("drunk:\t" + druncate (d));
		System.out.println ("trunc:\t" + truncate (d));
		System.out.println ("--------------");
	}

	private double druncate (double x)
	{
		long y = (long) (x * 100);
		return (double) y / 100;
	}

	private double truncate (double x)
	{
		DecimalFormat df = new  DecimalFormat ("0.##");
		String d = df.format (x);
		System.out.println ("\tformatted: " + d);
		d = d.replaceAll (",", ".");
		Double dbl = new Double (d);
		return dbl.doubleValue ();
	}
Locales may make your life complicated ...

seeking a job as java-programmer in Berlin:
 
Okay then... what about
Code:
private static double truncate(double x){
  return Math.floor(x * 100)/100;
}

Tim
---------------------------
"Your morbid fear of losing,
destroys the lives you're using." - Ozzy
 
... or to be correct for negative numbers too ...
Code:
private static double truncate(double x){
  if ( x > 0 )
    return Math.floor(x * 100)/100;
  else
    return Math.ceil(x * 100)/100;
}

[smile]

Tim
---------------------------
"Your morbid fear of losing,
destroys the lives you're using." - Ozzy
 
Yes. But it is then a decision by lowbk whether to take the performance hit of the longer solution which preserves the full Double range, or use the faster version which loses a small fraction of the Double range.

It depends on what he's using it for (which he doesn't state in the OP). Like a lot of things, it's a trade-off.

Tim
---------------------------
"Your morbid fear of losing,
destroys the lives you're using." - Ozzy
 
This is the output from the program
Code:
d:      1.0E30
drunk:  9.223372036854776E16
        formatted: 1000000000000000000000000000000
trunc:  1.0E30
--------------
d:      0.9090909
drunk:  0.9
        formatted: 0,91
trunc:  0.91
--------------
d:      1234.123456
drunk:  1234.12
        formatted: 1234,12
trunc:  1234.12
--------------
d:      9090909.9090909
drunk:  9090909.9
        formatted: 9090909,91
trunc:  9090909.91
If you may choose between a fast result and a correct result , the correct result is correct.

We shouldn't encourage beginners to use probably wrong results for (mostly irrelevant) performance-issuse.

Rules of Optimization:
Rule 1: Don't do it.
Rule 2: (for experts only): Don't do it yet.
(M. A. Jackson)

More computing sins are committed in the name of efficiency (without neccessarily achieving it) than for any other single reason - including blind stupidity.
(W. A. Wulf)

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil..
(Donald Knuth)



seeking a job as java-programmer in Berlin:
 
Okay okay. I agree with you. Correct results are paramount unless there are strong identifiable reasons for eroding them in the name of efficiency.

One point however ... he wanted to truncate to 2 dps. You're solution appears to be rounding to the nearest 2 dps.

Tim
---------------------------
"Your morbid fear of losing,
destroys the lives you're using." - Ozzy
 
I've tried to come up with a solution (truncate2) which will correctly truncate upto Double.MAX_VALUE without recourse to String manipulation.
Code:
  public static void main(String[] args) {
    checkDouble(999999999999999999999999999999.999999999);
    checkDouble(0.9090909);
    checkDouble(1234.123456);
    checkDouble(9090909.9090909);
    checkDouble(Double.MAX_VALUE);
    checkDouble(Double.MIN_VALUE);
  }
  
  private static void checkDouble (double d)
      {
          System.out.println ("d:\t" + d);
          System.out.println ("drunk:\t" + druncate (d));
          System.out.println ("trunc:\t" + truncate (d));
          System.out.println ("trunc2:\t" + truncate2 (d));
          System.out.println ("--------------");
      }

  private static double druncate(double x) {
    if ( x > 0 )
      return Math.floor(x * 100)/100;
    else
      return Math.ceil(x * 100)/100;
  }

  private static double truncate (double x){
    DecimalFormat df = new DecimalFormat("0.##");
    String d = df.format(x);
    System.out.println("\tformatted: " + d);
    d = d.replaceAll(",", ".");
    Double dbl = new Double(d);
    return dbl.doubleValue();
  }

  [b]// A correct non-string solution????[/b]
  private static double truncate2 (double x){
    double fract;
    double whole;
    if ( x > 0 ){
      whole = Math.floor(x);
      fract = Math.floor( (x - whole) * 100) / 100;
    } else {
      whole = Math.ceil(x);
      fract = Math.ceil( (x - whole) * 100) / 100;
    }

    return whole + fract;
  }

This gives output :-
Code:
d:	1.0E30
drunk:	9.223372036854776E16
	formatted: 1000000000000000000000000000000
trunc:	1.0E30
trunc2:	1.0E30
--------------
d:	0.9090909
drunk:	0.9
	formatted: 0.91
trunc:	0.91
trunc2:	0.9
--------------
d:	1234.123456
drunk:	1234.12
	formatted: 1234.12
trunc:	1234.12
trunc2:	1234.12
--------------
d:	9090909.9090909
drunk:	9090909.9
	formatted: 9090909.91
trunc:	9090909.91
trunc2:	9090909.9
--------------
d:	1.7976931348623157E308
drunk:	9.223372036854776E16
	formatted: 17976931348623157000000000000000000000000000000 (and so on)
trunc:	1.7976931348623157E308
trunc2:	1.7976931348623157E308
--------------
d:	4.9E-324
drunk:	0.0
	formatted: 0
trunc:	0.0
trunc2:	0.0
--------------

Will this pass?

Tim
---------------------------
"Your morbid fear of losing,
destroys the lives you're using." - Ozzy
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top