Javascript arithmetic fun

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: winston, another_commander

Post Reply
User avatar
Micha
Commodore
Commodore
Posts: 815
Joined: Tue Sep 02, 2008 2:01 pm
Location: London, UK
Contact:

Javascript arithmetic fun

Post by Micha »

Javascript doesn't know types - variables are whatever type makes sense at the time.

eg:

Code: Select all

var i = 1; // Number
var j = "1"; // String
var k = i + j; // "11" -> probably what wasn't expected.
The reason k contains "11" instead of 2 is that j is a string and Javascript ends up using string concatenation rather than arithmetic to compute the value for k.

To work around this, always use parseInt() when working with variables whose type you're not 100% sure of:

Code: Select all

var k = parseInt(i) + parseInt(j); // 2 -> probably what was expected.

This was the underlying reason for an odd bug whereby scooping sometimes filled my cargohold from a single barrel. The culprit was the new player.ship.manifest object and the way cargo is awarded using it.

eg:

Code: Select all

player.ship.manifest["food"] += 1; // Award 1 ton of Food
In this case though, the quantity was first retrieved from somewhere else, then printed as a string, before being awarded. Printing the quantity as a string converted it to a string type and then stuffed up the next calculation.

Code: Select all

var quantity = <something>;
player.consoleMessage(quantity + "<some string>");
player.ship.manifest["food"] += quantity; // WARNING
The fix is to either award the cargo before performing the string operation, or to make really sure, wrap quantity in parseInt:

Code: Select all

player.ship.manifest["food"] += parseInt(quantity); // Ok
The glass is twice as big as it needs to be.
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Re: Javascript arithmetic fun

Post by JensAyton »

Micha wrote:
To work around this, always use parseInt() when working with variables whose type you're not 100% sure of:

Code: Select all

var k = parseInt(i) + parseInt(j); // 2 -> probably what was expected.
…unless of course you wanted a floating-point value, in which case you want parseFloat() – or the unary + operator:

Code: Select all

var k = +i + +j;
User avatar
Eric Walch
Slightly Grand Rear Admiral
Slightly Grand Rear Admiral
Posts: 5536
Joined: Sat Jun 16, 2007 3:48 pm
Location: Netherlands

Post by Eric Walch »

Yes, this also irritates me sometimes, not being able to define your types. There are probably rules how additions are handled. Adding a number and a sting seems always to result in a string.

In your above example the quantity was already defined as a string in the original oxp were you got the example from. I did read the quantity in from shipdata.plist with

Code: Select all

var quantity = this.ship.scriptInfo.quantity;
However, quantity was defined there as string in my older versions. With the old awardCargo() this was never a problem so I never noticed this. For the new awarding method, the type must be correct. Changing the definition in the xml.plist as integer fixed it. Even printing that integer as part of a string kept its integer type intact.
User avatar
Kaks
Quite Grand Sub-Admiral
Quite Grand Sub-Admiral
Posts: 3009
Joined: Mon Jan 21, 2008 11:41 pm
Location: The Big Smoke

Post by Kaks »

In other words, the easiest way to modify the script would be to do the following:

Code: Select all

player.ship.manifest["food"] += +quantity;
though I must confess uneasiness when using the unary +, since it's normally indistingushable from the string concatenation +. If you're just as uneasy about it, an old & time honoured js 'trick' is to do

Code: Select all

player.ship.manifest["food"] += quantity-0;
instead.

Hope this helps :)
Hey, free OXPs: farsun v1.05 & tty v0.5! :0)
User avatar
JensAyton
Grand Admiral Emeritus
Grand Admiral Emeritus
Posts: 6657
Joined: Sat Apr 02, 2005 2:43 pm
Location: Sweden
Contact:

Post by JensAyton »

When I design my Perfect Language™, it will have distinct operators for addition and concatenation. And probably for dot product and cross product, too. :-)
Post Reply