waterml/src/main/java/ucar/nc2/ogc/erddap/util/ErddapString2.java
public static int[] toRational(double d) {        
        if (d == 0)
            return new int[]{0, 0};

        if (!ErddapMath2.isFinite(d))
            return new int[]{1, Integer.MAX_VALUE};

        String s = "" + d; //-12.0 or 6.6260755E-24
        //String2.log("\nd=" + d + "\ns=" + s);
        int ten = 0;

        //remove the e
        int epo = s.indexOf('E');
        if (epo > 0) {
            ten = parseInt(s.substring(epo + 1));
            s = s.substring(0, epo);
            //String2.log("remove E s=" + s + " ten=" + ten);
        }

        //remove .0; remove decimal point
        if (s.endsWith(".0"))
            s = s.substring(0, s.length() - 2);
        int dpo = s.indexOf('.');
        if (dpo > 0) {
            ten -= s.length() - dpo - 1;
            s = s.substring(0, dpo) + s.substring(dpo + 1);
            //String2.log("remove . s=" + s + " ten=" + ten);
        }

        //convert s to long
        //need to lose some precision?
        long tl = parseLong(s);    
        //String2.log("tl=" + tl + " s=" + s);
        while (Math.abs(tl) > 1000000000) {
            tl = Math.round(tl / 10.0);
            ten++;
            //String2.log("tl=" + tl + " ten=" + ten);
        }
        //remove trailing 0's
        while (tl != 0 && tl / 10 == tl / 10.0) {
            tl /= 10;
            ten++;
            //String2.log("remove 0 tl=" + tl + " ten=" + ten);
        }
        //add up to 3 0's?
        if (tl < 100000 && ten >= 1 && ten <= 3) {
            while (ten > 0) {
                tl *= 10;
                ten--;
            }
        }

        return new int[]{(int)tl, ten}; //safe since large values handled above
    }
public static int[] toRational(double d) {        
        if (d == 0)
            return new int[]{0, 0};

        if (!ErddapMath2.isFinite(d))
            return new int[]{1, Integer.MAX_VALUE};

        String s = "" + d; //-12.0 or 6.6260755E-24
        //String2.log("\nd=" + d + "\ns=" + s);
        int ten = 0;

        //remove the e
        int epo = s.indexOf('E');
        if (epo > 0) {
            ten = parseInt(s.substring(epo + 1));
            s = s.substring(0, epo);
            //String2.log("remove E s=" + s + " ten=" + ten);
        }

        //remove .0; remove decimal point
        if (s.endsWith(".0"))
            s = s.substring(0, s.length() - 2);
        int dpo = s.indexOf('.');
        if (dpo > 0) {
            ten -= s.length() - dpo - 1;
            s = s.substring(0, dpo) + s.substring(dpo + 1);
            //String2.log("remove . s=" + s + " ten=" + ten);
        }

        //convert s to long
        //need to lose some precision?
        long tl = parseLong(s);    
        //String2.log("tl=" + tl + " s=" + s);
        while (Math.abs(tl) > 1000000000) {
            tl = Math.round(tl / 10.0);
            ten++;
            //String2.log("tl=" + tl + " ten=" + ten);
        }
        //remove trailing 0's
        while (tl != 0 && tl / 10 == tl / 10.0) {
            tl /= 10;
            ten++;
            //String2.log("remove 0 tl=" + tl + " ten=" + ten);
        }
        //add up to 3 0's?
        if (tl < 100000 && ten >= 1 && ten <= 3) {
            while (ten > 0) {
                tl *= 10;
                ten--;
            }
        }

        return new int[]{(int)tl, ten}; //safe since large values handled above
    }
public static int [ ] toRational ( double d ) { if ( d == 0 ) return new int [ ] { 0 , 0 } ; if ( ! ErddapMath2 . isFinite ( d ) ) return new int [ ] { 1 , Integer . MAX_VALUE } ; String s = "" + d ; //-12.0 or 6.6260755E-24 //String2.log("\nd=" + d + "\ns=" + s); int ten = 0 ; //remove the e int epo = s . indexOf ( ' ' ) ; if ( epo > 0 ) { ten = parseInt ( s . substring ( epo + 1 ) ) ; s = s . substring ( 0 , epo ) ; //String2.log("remove E s=" + s + " ten=" + ten); } //remove .0; remove decimal point if ( s . endsWith ( ".0" ) ) s = s . substring ( 0 , s . length ( ) - 2 ) ; int dpo = s . indexOf ( ' ' ) ; if ( dpo > 0 ) { ten -= s . length ( ) - dpo - 1 ; s = s . substring ( 0 , dpo ) + s . substring ( dpo + 1 ) ; //String2.log("remove . s=" + s + " ten=" + ten); } //convert s to long //need to lose some precision? long tl = parseLong ( s ) ; //String2.log("tl=" + tl + " s=" + s); while ( Math . abs ( tl ) > 1000000000 ) { tl = Math . round ( tl / 10.0 ) ; ten ++ ; //String2.log("tl=" + tl + " ten=" + ten); } //remove trailing 0's while ( tl != 0 && tl / 10 == tl / 10.0 ) { tl /= 10 ; ten ++ ; //String2.log("remove 0 tl=" + tl + " ten=" + ten); } //add up to 3 0's? if ( tl < 100000 && ten >= 1 && ten <= 3 ) { while ( ten > 0 ) { tl *= 10 ; ten -- ; } } return new int [ ] { ( int ) tl , ten } ; //safe since large values handled above }
This converts a double to a rational number (m * 10^t).
This is similar to Math2.mantissa and Math2.intExponent, but works via string manipulation
to avoid roundoff problems (e.g., with 6.6260755e-24).

@param d
@return int[2]: [0]=m, [1]=t.
(or {0, 0} if d=0, or {1, Integer.MAX_VALUE} if !finite(d))
This converts a double to a rational number ( m * 10^t ) . This is similar to Math2 . mantissa and Math2 . intExponent but works via string manipulation to avoid roundoff problems ( e . g . with 6 . 6260755e - 24 ) .