0

Long story short, I'm working in a system that only works with groovy in its expression editor, and I need to create a function that returns the number of significant figures an integer has. I've found the following function in stack overflow for Java, however it doesnt seem like groovy (or the system itself) likes the regex:

String myfloat = "0.0120";

String [] sig_figs = myfloat.split("(^0+(\\.?)0*|(~\\.)0+$|\\.)");

int sum = 0;

for (String fig : sig_figs)
{
    sum += fig.length();
}

return sum;

I've since tried to convert it into a more Groovy-esque syntax to be compatible, and have produced the following:

def sum = 0;

def myint = toString(mynum);

def String[] sig_figs = myint.split(/[^0+(\\.?)0*|(~\\.)0+$|\\.]/);

for (int i = 0; i <= sig_figs.size();i++)
{
    sum += sig_figs[i].length();
}
return(sum); 

Note that 'mynum' is the parameter of the method

It should also be noted that this system has very little visibility in regards to what groovy functions are available in the system, so the solution likely needs to be as basic as possible

Any help would be greatly appreciated. Thanks!

jrack11
  • 3
  • 2
  • 1
    I believe there is a code syntax error in your definition of the `sig_figs` variable. You should probably have either `def` or `String[]`, but not both. – schwissig Aug 31 '22 at 21:10
  • `def String[]` is weird and unnecessary, but it's valid groovy – tim_yates Aug 31 '22 at 21:36
  • What is your actual problem here? If I run your version, I get an index-out-of-bounds-error, which means, your `<=` is wrong in the for. Is your environment not showing those kind of errors? Consider using the `groovysh` and then paste the working code in your env. Why are you asking for "integer" and then your code talks about floats and `.` in the regexp - are those `.` thousand separators? – cfrick Sep 01 '22 at 12:32

2 Answers2

1

I think this is the regex you need:

def num = '0.0120'
def splitted = num.split(/(^0+(\.?)0*|(~\.)0+$|\.)/)
def sf = splitted*.length().sum()
daggett
  • 26,404
  • 3
  • 40
  • 56
tim_yates
  • 167,322
  • 27
  • 342
  • 338
0

It's been a while since I've had to think about significant figures, so sorry if I have the wrong idea. But I've made two regular expressions that combined should count the number of significant figures (sorry I'm no regex wizard) in a string representing a decimal. It doesn't handle commas, you would have to strip those out.

This first regex matches all significant figures before the decimal point

([1-9]+\d*[1-9]|[1-9]+)

And this second regex matches all significant figures after the decimal point:

\.((\d*[1-9]+)+)?

If you add up the lengths of the first capture group (or 0 when no match) for both matches, then it should give you the number of significant figures.

Example:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SigFigs {

    private static final Pattern pattern1 = Pattern.compile("([1-9]+\\d*[1-9]|[1-9]+)");
    private static final Pattern pattern2 = Pattern.compile("\\.((\\d*[1-9]+)+)?");

    public static int getSignificantFigures(String number) {
        int sigFigs = 0;
        for (int i=0; i < 2; i++) {
            Matcher matcher = (i == 0 ? pattern1 : pattern2).matcher(number);
            if (matcher.find()) {
                try {
                    String s = matcher.group(1);
                    if (s != null) sigFigs += s.length();
                } catch (IndexOutOfBoundsException ignored) { }
            }
        }
        return sigFigs;
    }
    
    public static void main(String[] args) {
        System.out.println(getSignificantFigures("0305.44090")); // 7 sig. figs
    }

}

Of course using two matches is suboptimal (like I've said, I'm not crazy good at regex like some I could mention) but its fairly robust and readable

Wasabi Thumbs
  • 303
  • 1
  • 2
  • 8
  • This was super helpful and it looks like it works in most cases, although it does count trailing zeros. For example, 100 returns 3 sig figs when it should return 1. If you don't mind, could you reply with the regex code for before the decimal? I'm very new to coding and it would mean a lot! Thanks! – jrack11 Sep 02 '22 at 20:35
  • Oh didn't consider that, will update later. – Wasabi Thumbs Sep 03 '22 at 00:13
  • Actually, I'm not sure why you're getting 3 sig figs for 100. The first pattern only matches sequences that end in a number between 1 and 9, unless the alternation operator works differently specifically for Java regex – Wasabi Thumbs Sep 03 '22 at 00:15