BigRational.js icon indicating copy to clipboard operation
BigRational.js copied to clipboard

make bigRat("0.35%") work

Open ghost opened this issue 9 years ago • 1 comments

Happy to have a go at this myself presently.

ghost avatar Feb 29 '16 15:02 ghost

Easy way to do this is here... "0.35%" this is a string. So you can so this with this code:

var str = "354.25%";
if(str.indexOf("%") !== -1 ){
    var n = bigRat(str.substr(0, str.indexOf("%"))).divide(bigRat('100'));
}
//output
document.write(n.toString(), '==', n.toDecimal());

I did found in the source code the parse function with name "function parse(a, b) {...}" So you can put there, in the end - this code:

	if(text.indexOf("%")!==-1){return parseDecimal(text.substr(0, text.indexOf("%"))).divide(bigRat('100'));}
        return parseDecimal(text);

test:

var str = "354.25%";
var bigrat = bigRat(str);
console.log(bigrat.toString(), '=', bigrat.toDecimal());

But for example, bigRat not working correctly with

var string = "2_1/3%"

and need do more changes.

So I did rewrite BigRational JS to add supporting persents. You can see the code here. BigRational.js:

    function parse(a, b) {
        if(!a) {
            return new BigRational(bigInt(0), bigInt[1]);
        }
        if(b) {
            return reduce(bigInt(a), bigInt(b));
        }
        if (bigInt.isInstance(a)) {
            return new BigRational(a, bigInt[1]);
        }
        if (a instanceof BigRational) return a;

        var num;
        var denom;

        var text = String(a);
        var persents = text.split("%");
        if(persents.length>2){
            throw new Error("Invalid input: too many '%' tokens");
        }
        if(persents.length>1){
            text = persents[0];
            var persent = true;
        }
        
        var texts = text.split("/");
        if(texts.length > 2) {
            throw new Error("Invalid input: too many '/' tokens");
        }
        if(texts.length > 1) {
            var parts = texts[0].split("_");
            if(parts.length > 2) {
                throw new Error("Invalid input: too many '_' tokens");
            }
            if(parts.length > 1) {
                var isPositive = parts[0][0] !== "-";
                num = bigInt(parts[0]).times(texts[1]);
                if(isPositive) {
                    num = num.add(parts[1]);
                } else {
                    num = num.subtract(parts[1]);
                }
                denom = bigInt(texts[1]);
                return (persent) ? reduce(num, denom).divide(bigRat('100')) : reduce(num, denom);
            }
            return (persent) ? reduce(bigInt(texts[0]), bigInt(texts[1])).divide(bigRat('100')) : reduce(bigInt(texts[0]), bigInt(texts[1]));
        }
        return (persent) ? parseDecimal(text).divide(bigRat('100')) : parseDecimal(text);
    }

test:

<script language="JavaScript" type="text/javascript" src="../BigInteger.js"></script>
<!-- 	This need to require bigInteger previous	↑ -->
<script language="JavaScript" type="text/javascript" src="BigRational.js"></script>
<script>
var str = "354.25%";
var bigrat = bigRat(str);
document.write('<br>', str, ' = ', bigrat.toString(), ' = ', bigrat.toDecimal());

var str = "2_1/3%";
var bigrat = bigRat(str);
document.write('<br>', str, ' = ', bigrat.toString(), ' = ', bigrat.toDecimal());

var str = "1/3%";
var bigrat = bigRat(str);
document.write('<br>', str, ' = ', bigrat.toString(), ' = ', bigrat.toDecimal());

var str = "0.00003%";
var bigrat = bigRat(str);
document.write('<br>', str, ' = ', bigrat.toString(), ' = ', bigrat.toDecimal());
</script>

result

354.25% = 1417/400 = 3.5425
2_1/3% = 7/300 = 0.0233333333
1/3% = 1/300 = 0.0033333333
0.00003% = 3/10000000 = 0.0000003

username1565 avatar May 28 '18 21:05 username1565