4

There's been a lot of questions on rounding by significant figures, and answers that that provides a new method to do the rounding, such as:

Rounding to an arbitrary number of significant digits

Round a double to 2 decimal places

Most of these questions and solutions are around 2009~2010.

I want to have a simple built in method (or from standard well know libraries such as from Apache or Spring) that given the number and significant figures, prints out the number limited to the specified significant figure.

Ie:

  • 123.456789 // to 2 signficant figures: 120
  • 123.456789 // to 4 signficant figures: 123.4
  • 123.456789 // to 7 signficant figures: 123.4567
Community
  • 1
  • 1
JackDev
  • 11,003
  • 12
  • 51
  • 68
  • There is a [Unicode Library mentioned in response to a similar question](http://stackoverflow.com/questions/5474742/is-there-a-java-number-formatting-library-that-handles-significant-digits) that might do what you want. – Carlos Salazar Oct 21 '13 at 06:30
  • 2
    See here http://stackoverflow.com/questions/7572309/any-neat-way-to-limit-significant-figures-with-bigdecimal – Stanislav Mamontov Oct 21 '13 at 06:33
  • @Carlos: thanks, I saw that, but didn't want to use library from com.ibm.icu.text. – JackDev Oct 21 '13 at 23:02
  • @Stanislav: +1. Would be the answer if they didn't have the bit of processing to calculate the scales. – JackDev Oct 21 '13 at 23:04
  • If you don't care that it's in scientific notation, you could use [DecimalFormat](http://download.java.net/jdk7/archive/b123/docs/api/java/text/DecimalFormat.html). To get it out of scientific notation is straightforward, but probably slower than manually doing it. – kevmo314 Oct 21 '13 at 23:36
  • Thanks @Kevmo. Though I also want to be able to specify significant figures for non decimal points. Ie. 123456.1234 to 3 sig fig becomes 123000 – JackDev Oct 21 '13 at 23:52
  • 1
    Right, which is why you can abuse scientific notation. 123456.1234 to 3 sig figs is 1.23e5, which is the same answer. :) – kevmo314 Oct 21 '13 at 23:54
  • Hahaha, @Kevmo, +1 for thinking outside the box! =D – JackDev Oct 21 '13 at 23:55

2 Answers2

2

I found this nice way of doing it using String format. Apparently, users can specify maximum number of significant digits with a string format 'g' or 'G'. (http://developer.android.com/reference/java/util/Formatter.html)

This is if you just want to print it out.

public String toSignificantFiguresString(BigDecimal bd, int significantFigures){
    return String.format("%."+significantFigures+"G", bd);
}

This is if you want to convert it:

public BigDecimal toSignificantFigures(BigDecimal bd, int significantFigures){
    String s = String.format("%."+significantFigures+"G", bd);
    BigDecimal result = new BigDecimal(s);
    return result;
}

Here's an example of it in action:

    BigDecimal bd = toSignificantFigures(BigDecimal.valueOf(12345678.123456789), 10);
    System.out.println("bd: " + String.format("%f",bd));

NB: I'm using BigDecimal for calculation because double and float has a precision problems.)

JackDev
  • 11,003
  • 12
  • 51
  • 68
0

Not quite right. To get it perfect:

public String toSignificantFiguresString(BigDecimal bd, int significantFigures ){
    String test = String.format("%."+significantFigures+"G", bd);
    if (test.contains("E+")){
        test = String.format(Locale.US, "%.0f", Double.valueOf(String.format("%."+significantFigures+"G", bd)));
    }
    return test;
}
heights1976
  • 480
  • 6
  • 16