ID:2728718
 
Resolved
Several new math procs have been added:
  • floor(x): the value of x, rounded down to the nearest integer; this is an alias for round(x) with no second argument
  • ceil(x): the value of x, rounded up to the nearest integer
  • trunc(x): the value of x rounded toward zero to an integer; that is, the integer part of the number
  • fract(x): the fractional part of x
  • isnan(x): true of x is a numeric type but is an invalid number (NaN)
  • isinf(x): true if x is a positive or negative infinity
Applies to:DM Language
Status: Resolved (515.1590)

This issue has been resolved.
Currently, round(x) returns a floored x for whatever reason (at least it's documented). To actually round the value one must use
round(x, 1)
which is silly and confusing.

It would be a lot clearer (and probably faster) if floor() and round() were separate functions. I'm aware changing the functionality of round() will likely skew the intended function of some code and will require it to be updated. But I've encountered disproportionately more code that's already skewed because the developer assumed the round() function acted the same way it does in every other language, by rounding xD.

Currently the fastest and cleanest way to get the ceiling is
-round(-x)
and truncation (well, the closest thing to it)
round(x >=0 ? x : -x)

There's no good reason I can think of that these two couldn't be moved into the DM language itself. It saves performance at best and reduces pre-processing time and developer workload at worst
bump for 515
Why not keep round() and just add ceil() and floor()?

round() could point them towards using floor() instead when compiled, while keeping it in for backwards compatibility.

Could remove it from the documented features and put it in a page for removed/redundant features that's in the reference.
In response to Kozuma3
I'm not suggesting the removal of round(), I'm suggesting that round(x) actually rounds the value instead of flooring it
In response to TheFakeElon
This behavior is exceedingly unlikely to change, given the amount of code out there that could break since the assumption of flooring is no longer valid.
In response to Popisfizzy
Nobody assumes the function named round() floors the value. That's something you only really find out by diving into the byond ref and looking at mundane proc documentation. I think it's fair to assume there's currently far more math that's skewed because of that quirk than math that would become skewed if round were "fixed".

It'd be a net benefit for BYOND in the long run, we've changed stuff before at the expense of backwards compatibility, although in this case said expense would be much more ambiguous given how much code would be accidentally fixed :)
In response to TheFakeElon
So all code that intentionally uses round(x) as floor(x) should be broken... for a chance at accidentally fixing code that was written based on incorrect assumptions and was left broken because no one noticed an issue?
So all code that intentionally uses round(x) as floor(x) should be broken... for a chance at accidentally fixing code that was written based on incorrect assumptions and was left broken because no one noticed an issue?

QFE

There are plenty of bad decisions in the engine to rabble rouse over. This one isn't one of them. There are some things that can be fixed, and some that can't once we've headed this far down the road. This one's just a semantic preference at this point, and would cause more harm than good to fix.

I'd like built in floor(), truncate() and ceil() functions though. Leave round()ney alone.
In response to Ter13
Ter13 wrote:
So all code that intentionally uses round(x) as floor(x) should be broken... for a chance at accidentally fixing code that was written based on incorrect assumptions and was left broken because no one noticed an issue?

QFE

There are plenty of bad decisions in the engine to rabble rouse over. This one isn't one of them. There are some things that can be fixed, and some that can't once we've headed this far down the road. This one's just a semantic preference at this point, and would cause more harm than good to fix.

I'd like built in floor(), truncate() and ceil() functions though. Leave round()ney alone.

Something like this should be addressed in my opinion.

Simply document breaking API changes and fix this during a major version bump.

Developers should then read about breaking changes before building with a new major version.
I've added floor(), ceil(), trunc(), and fract() for 515.

Internally, floor() is just the 1-argument format of round(). The 1-arg form of round() has been left alone for legacy reasons.

Edit: I'm actually open to truncate() and fraction() instead if those are preferable. fract() is at least consistent with some shader usage.
I think trunc and fract are fine
Lummox JR resolved issue with message:
Several new math procs have been added:
  • floor(x): the value of x, rounded down to the nearest integer; this is an alias for round(x) with no second argument
  • ceil(x): the value of x, rounded up to the nearest integer
  • trunc(x): the value of x rounded toward zero to an integer; that is, the integer part of the number
  • fract(x): the fractional part of x
  • isnan(x): true of x is a numeric type but is an invalid number (NaN)
  • isinf(x): true if x is a positive or negative infinity