int() is flooring, not integerizing, variables

Bugs will be moved here once resolved.

Post » Tue Nov 22, 2016 12:29 am

Problem Description
int() is performing a flooring operation on variables. This is not what casting to int does in any programming language, ever.

Given the example, Variable1 = -0.6, when doing int(Variable1), it should return 0 and there are extremely valid reasons for this. Like when you're doing basic movement operations like "int(sin(270) * speed * dt)". At an angle of 270, for instance, there should be 0 movement from the Y axis. However, int is flooring. Flooring will take a number like -0.6 and make it the next lowest integer, which is, in the case of my example, -1.

The interesting part about this bug is that it only does it in this order. If you do int(-0.6), it will properly integerize it. I assume this is a static evaluation that occurs during compile time.

Observed Result
Variable1 = -0.6
int(Variable1) returns -1

Expected Result
0

Steps to Reproduce Bug
  • Create variable by name of "Variable1"
  • Set Variable1 to -0.6
  • Print out "int(Variable1)"

Affected Browsers
  • Chrome: YES
  • FireFox: YES
  • Internet Explorer: YES

Operating System and Service Pack
Any

Construct 2 Version ID
240

Where?
The bug is in expressions.js, with this line of code
Code: Select all
ExpValue.prototype.set_int = function (val)
   {
      assert2(cr.is_number(val), "Calling expvalue.set_int without number type");

      this.type = cr.exptype.Integer;
      this.data = Math.floor(val);
   };


To fix it you need to do a typical JS int casting operation using a bitwise or op with 0.

Code: Select all
this.data = val | 0;


Alternative fix that doesn't truncate the larger integer values that can be stored as a float.

Code: Select all
this.data = parseInt(val, 10);


Clarification for anyone confused by my post
This is the difference between floor, ceil, round, and int. I provided what results you should get and how it works (and some alternative examples if that helps).

floor(-1.6) should return -2
floor(1.6) should return 1
How it works: int(value) < 0 ? int(value) - 1 : int(value)
Alternative how it works: int(value) - 1 * (value < 0 ? 1 : 0)

ceil(-1.6) should return -1
ceil(1.6) should return 2
How it works: int(value) >= 0 ? int(value) + 1: int(value)
Alternative how it works: int(value) + 1 * (value >= 0 ? 1 : 0)

round(-1.6) should return -2
round(1.6) should return 2
How it works: int(value + 0.5 * (value < 0 ? -1 : 1))

int(-1.6) should return -1
int(1.6) should return 1

If your code currently uses int() and is stable, replace it with floor(), cause that's what int() is doing right now except that you'll have the proper function name.

Definition of "integerizing"
This is programming jargon that I'm incredibly accustomed to and expect everyone to know, but this was obviously a lousy assumption on my part. So I'll provide the definition here.
To "integerize" is the act of casting, usually, a 32-bit or 64-bit floating point value to a 32-bit integer with the purpose of trimming off the decimal points, leaving only the whole number and its sign (- +).
Last edited by goodlookinguy on Tue Nov 22, 2016 6:49 pm, edited 13 times in total.
B
13
S
5
G
10
Posts: 5
Reputation: 5,459

Post » Tue Nov 22, 2016 1:05 am

http://www.dictionary.com/browse/integer

Even if it's not something other languages do he's not going to change it now.
Image ImageImage
B
171
S
50
G
180
Posts: 8,394
Reputation: 113,982

Post » Tue Nov 22, 2016 1:11 am

Why did you provide a link to the def of integer? I'm a software engineer...oh, wait, are you confusing "language" with "spoken language". I'm saying "language," as in, "programming language."

As far as your other statement goes, well, I'm going to have to say that you're wrong there. Doing int(-0.6) gives a different result than "Variable1 = -0.6" followed by "int(Variable1)". This is an extremely valid and ridiculously simple to fix bug.
B
13
S
5
G
10
Posts: 5
Reputation: 5,459

Post » Tue Nov 22, 2016 1:38 am

goodlookinguy wrote:Why did you provide a link to the def of integer? I'm a software engineer...oh, wait, are you confusing "language" with "spoken language". I'm saying "language," as in, "programming language."

As far as your other statement goes, well, I'm going to have to say that you're wrong there. Doing int(-0.6) gives a different result than "Variable1 = -0.6" followed by "int(Variable1)". This is an extremely valid and ridiculously simple to fix bug.



Well for one thing integerizing isn't word, and this software is made for people that use that particular language.
I mean the spoken one not the one that requires coding knowledge.

As far as the other statement goes it would break existing projects.
If you are unhappy with the way it works it is ridiculously easy to work around.
Image ImageImage
B
171
S
50
G
180
Posts: 8,394
Reputation: 113,982

Post » Tue Nov 22, 2016 1:48 am

...I'm sorry, but no. This is a bug that needs fixing. People can fix their projects to match this (by replacing int() with floor()), but it's atypical, inconsistent, behavior. You can't possibly expect a serious group to use the product when simple bugs that like aren't even stomped out.

Plus, you don't work for Scirra as far as I can tell, so stop talking on their behalf, as if you do. I'm not interested in your guesses.

Also, "integerizing" is programming jargon referring to the act of casting a 32-bit or 64-bit floating point value to a 32-bit integer. So please stop acting like you know everything.
Last edited by goodlookinguy on Tue Nov 22, 2016 3:51 am, edited 1 time in total.
B
13
S
5
G
10
Posts: 5
Reputation: 5,459

Post » Tue Nov 22, 2016 1:52 am

I'll try to work on my acting.

Good luck with yours.
Image ImageImage
B
171
S
50
G
180
Posts: 8,394
Reputation: 113,982

Post » Tue Nov 22, 2016 12:43 pm

@newt - please don't needlessly start a flamewar in a bug report. The specific words people use isn't really important as long as they convey the bug report clearly.

@goodlookinguy - the main issue with changing this is it seems likely this would break existing projects in weird and subtle ways. If someone's game breaks due to the rounding direction changing, it will probably be a nightmare to figure out the chain of consequences. The int expression primarily exists for converting strings to ints, but does also floor a float it's passed to make sure it always returns a whole number. This probably should not actually be done at all, since neither C2 nor Javascript actually have a formal integer type. It's mostly just a thoughtless carry-over from Construct Classic that shouldn't really have been added. On the other hand if you actually intend to round a float I guess you'd either use floor(), ceil() or round().

Another issue is val | 0 truncates to a signed 32-bit integer, whereas normal JS floats have 53-bit integer precision, as per the precision of a double. So actual integer truncation would probably also break projects using the expression on very large numbers. (Some people like super-mega-high scores :P)

So I think there's too much to lose vs. not much to gain here, so I'd probably just file this under "weird quirks of C2". Maybe for C3 I should just deprecate the expression and add a separate StrToInt() expression or something like that?
Scirra Founder
B
399
S
236
G
89
Posts: 24,543
Reputation: 195,430

Post » Tue Nov 22, 2016 5:48 pm

Okay, but what about the inconsistency I pointed out? I understand if you want to keep it as a flooring op, but at least make it consistent because it was driving me crazy why I was getting inconsistent output.

int(-0.6) returns 0

Variable1 = -0.6
int(Variable1) returns -1

Edit: I know you won't change anything, but parseInt seems to do the exact same thing as the bitwise-version casting except that it handles larger than int32 values.
Code: Select all
this.data = parseInt(val, 10);
B
13
S
5
G
10
Posts: 5
Reputation: 5,459

Post » Tue Nov 22, 2016 8:26 pm

Maybe it would be a good idea to just rename the current int() function to strToInt() and add a new function which would simply do the JS parseInt() as a new one? If you just rename the function in the editor then it will not break the old projects and will be more consistent. Adding an equivalent of parseInt() seems to be a good idea as it looks like there's no standard int casting in C2 currently.
ImageImageImage
B
28
S
17
G
82
Posts: 1,031
Reputation: 45,906


Return to Closed bugs

Who is online

Users browsing this forum: No registered users and 6 guests