prieston
prieston

Reputation: 1506

Show math operation syntax not result

I have a variable var x= 12/2 and i want to view it like this 12/2 and not 6. When I do x.toString() or String(x) i get the result as string. Is there a way to get the operation as it is and not the result when the original value is not string?

Upvotes: 1

Views: 104

Answers (6)

Oriol
Oriol

Reputation: 288080

Do NOT do this:

  1. Assuming this JS runs in a <script> element
  2. Use currentScript to get that element
  3. Use text to get the source code
  4. Somehow, parse it until you find your variable. In the following example I used regexp.
    Be aware JS is not a regular language, so can't be parsed properly by regexp.
  5. Obtain the expression assigned to the variable.

var x = 12 / 2;

var source = document.currentScript.text;
var expression = (source.match(/var x = (.+?);/) || [])[1];
document.write(expression);

Upvotes: 1

paxdiablo
paxdiablo

Reputation: 881323

When you actually execute a statement like:

var x = 12 / 2;

you actually lose information. The information lost is that which was used to create the result of the expression, which is the numerator and denominator. All you end us with is the result 6.

There is no way to get from that statement back to the original form since it's just as likely to be 24/4 or 594/99.

If you want to keep that information, you will need to store the value in such a way that it's not lost, such as creating a structure/class containing the numerator and denominator (i.e., a rational).

That way, you can get at those values, as well as calculating the result any time you need it.

There are numerous rational libraries floating around but you probably want to look for one that gives you the option of not normalising the numbers, such as turning 7/21 into 1/3.

Or you could choose something incredibly simple, such as:

"use strict";

class Rational {
    constructor(pnum, pden) {
        this.num = pnum;
        this.den = pden;
    }
    expr() {
        return "(" + this.num + "/" + this.den + ")";
    }
    result() {
        if (this.den === 0) {
            if (this.num === 0) {
                return "undefined";
            }
            return "infinite";
        }
        return this.num / this.den;
    }
}

var ratnum = new Rational(6, 4);
console.log(ratnum.expr());
console.log(ratnum.result());

That's using the ES6 class-based syntactic sugar. If you prefer the older style, it can also be done thus:

function Rational(pnum, pden) {
    this.num = pnum;
    this.den = pden;
};
Rational.prototype = {
    expr: function() {
        return "(" + this.num + "/" + this.den + ")";
    },
    result: function() {
        if (this.den === 0) {
            if (this.num === 0) {
                return "undefined";
            }
            return "infinite";
        }
        return this.num / this.den;
    }
};

var ratnum = new Rational(6, 4);
console.log(ratnum.expr());
console.log(ratnum.result());

In both those cases, you'll see the output in the two different ways:

(6/4)
1.5

Upvotes: 4

Ted A.
Ted A.

Reputation: 2302

As soon as you call var x = 12/2, the variable x is set to the value 6.

If you want to be able to show both '12/2' and the computed value, you could store your expression as a string, and use eval() (be very careful using this) to get the computed value of the expression.

But you could do:

var x = '12/2';
console.log(x); >> Outputs '12/2'
console.log(eval(x)); >> outputs 6

As many others have said, eval() should never be used on a string that didn't come directly from you, as it can open your site to security vulnerabilities.

From MDN:

eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension. More importantly, third party code can see the scope in which eval() was invoked, which can lead to possible attacks in ways to which the similar Function is not susceptible.

eval() is also generally slower than the alternatives, since it has to invoke the JS interpreter, while many other constructs are optimized by modern JS engines.

There are safer (and faster!) alternatives to eval() for common use-cases.

Upvotes: 2

djechlin
djechlin

Reputation: 60758

Your browser completely throws away 12/2 and just remembers 6. You can see this in action: Type 12/2<enter> into your console and that's what happens.

You need to also store 12/2. Probably by storing it as a string.

var stringVersion = '12/2';
var numberVersion = 12/2;
// The following are ways to get Javascript to convert the string to a number.
// They all come out to the value 12/2.
Number(stringVersion) === numberVersion; //true
+stringVersion === numberVersion; //true
eval(stringVersion) === numberVersion; //true

Normally eval leads to trouble (e.g. security attacks) but it's very illustrative here. Running eval on a string is like typing the string into the console and eval-uating it. So you can see in action how the text "12/2" converts to the number.

Upvotes: 1

Scott Marcus
Scott Marcus

Reputation: 65806

When you write an expression like:

 var x = 12 / 2;

You are writing an expression that needs to be evaluated. So, that's what the JS engine does.

There is one way that I can think of, and frankly I hesitate to tell you it because it is WIDELY considered to be one of the worst things you can do in JS (more to follow):

      var expression = "12 / 2";

      var result = eval(expression);

      alert(expression + " produces " + result);

Now, this may do what you want, but eval() is known to be EVIL because it will evaluate ANY string that you pass to it and that can open up security holes in an application. In addition, eval() brings any declarations it finds into the current scope, which can wipe out variables you were counting on.

Does this do what you ask? Yes. Should you do it? No!

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 816364

Is there a way to get the operation as it is and not the result when the original value is not string?

No, because 12/2 is an expression that gets evaluated before the assignment happens. You can't "reverse engineer" the original expression from the result.

Upvotes: 2

Related Questions