int() is flooring, not integerizing, variables

0 favourites
  • 9 posts
From the Asset Store
Easily store, modify, read and manipulate colors with Color Variables!
  • 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

    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);
    	};[/code:32wnyed3]
    
    To fix it you need to do a typical JS int casting operation using a bitwise or op with 0.
    
    [code:32wnyed3]this.data = val | 0;[/code:32wnyed3]
    
    Alternative fix that doesn't truncate the larger integer values that can be stored as a float.
    
    [code:32wnyed3]this.data = parseInt(val, 10);[/code:32wnyed3]
    
    [b]Clarification for anyone confused by my post[/b]
    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.
    
    [b]Definition of "integerizing"[/b]
    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 (- +).
  • http://www.dictionary.com/browse/integer

    Even if it's not something other languages do he's not going to change it now.

  • 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.

  • 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.

  • ...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.

  • I'll try to work on my acting.

    Good luck with yours.

  • 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.

    - 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 )

    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?

  • 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.

    this.data = parseInt(val, 10);[/code:3jbjqwuk]
  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • 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.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)