Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional Mathematical Constants and Functions #117

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

EliteMasterEric
Copy link

This proposal would implement several additional constants and functions into Math.

This proposal started when I realized Math.E didn't exist, and expanded as I thought about the main inconveniences of Math (i.e. having to nest Math.min calls and having to wrap many functions in Std.int even when the inputs were integers to begin with).

Feel free to suggest any additional functions to provide or critique the proposal.

@Simn
Copy link
Member

Simn commented Mar 4, 2024

I'd make a new function for the min/max thing, but I don't know what to call it.

The rest doesn't really need a haxe-evolution, but rather an implementation...

@RblSb
Copy link
Member

RblSb commented Mar 4, 2024

lerp is probably out of Math context, doesn't exist in other langs in Math classes? And while i prefer (t, a, b) args order, this is a less popular variation based on github search, and can be confusing to people. And it kinda feels lonely for me without unlerp / lerp remap and maybe clamp functions around.

If hypot will be implemented as extern, this will be slower than manual sqrt implementation because of some additional overflow checks, so it's needs mention maybe.

@hughsando
Copy link
Member

Not a fan of lerp, but the rest would be nice.
Is overloading min/max possible? This would be a nice solution as far as programming goes - perhaps problematic dynamically.
cpp.NativeMath has idiv and imod. Also it has cast-to-int, which uses the c++ machine code rules vs consistent rounding of Std.int. Some constants might be implement easily enough with something like final e = exp(1)
Convenience functions like "toRadians" might be good in MathTools for something like 180.toRadians(). Maybe the constants could be put in there too if they do not need special platform support.

@Simn
Copy link
Member

Simn commented Mar 5, 2024

A huge +1 for idiv from me. This is really annoying to do in Haxe at the moment and it shouldn't be.

@AndrewDRX
Copy link

AndrewDRX commented Mar 6, 2024

If expanding Math, then it might be nice to add a BigInteger class for arithmetic on arbitrarily large integers.

Well... at least according to some languages such as Java, it would exist as part of the standard Math libraries. Also for BC's C# library, which they most likely just based that off of the Java version when porting.

@Simn
Copy link
Member

Simn commented Mar 6, 2024

Let's please stay focused here, this is (and should be) about changes to the Math class itself.

@EliteMasterEric
Copy link
Author

If expanding Math, then it might be nice to add a BigInteger class for arithmetic on arbitrarily large integers.

Well... at least according to some languages such as Java, it would exist as part of the standard Math libraries. Also for BC's C# library, which they most likely just based that off of the Java version when porting.

If you feel the standard library deserves a BigInteger then you are free to write a separate proposal for that

@skial skial mentioned this pull request Mar 18, 2024
1 task
@thomasjwebb
Copy link

It would be great to have it monomorph to the right data type so that you can get a lot of these algorithms as int or float. Or at the very least. min and max should do that. I'm always doing this:

@:generic
static public inline function min<T:Float>(x:T, y:T):T
{
    return x > y ? y : x;
}

Some we have different versions based on what type it returns (ceil vs ceilf) but there are several where it would make sense to allow it to take and return int, avoiding unnecessary conversion. At least with min, max and abs. Maybe it could be argued that a generic min/max doesn't actually belong in Math because in principle that could apply to any Abstract that implements comparison operator but that would be confusing because float min/max is already there.

@Geokureli
Copy link

Geokureli commented Nov 8, 2024

It would be great to have it monomorph to the right data type so that you can get a lot of these algorithms as int or float. Or at the very least. min and max should do that. I'm always doing this:

Very much agree that min and max should gracefully handle floats V. ints. But, to be nit picky, I would do this via overloading, especially if Eric is proposing variadic min/max, and because I've had issues with <T:Float> uses like this in the past

class Test
{
  static function main()
  {
    // use simpler methods for 2 args
    $type(min(1  , 2     )); // type: Int  , output: 2 ints
    $type(min(1  , 2.0   )); // type: Float, output: 2 floats
    $type(min(1.0, 2     )); // type: Float, output: 2 floats
    $type(min(1.0, 2.0   )); // type: Float, output: 2 floats
    // more than two args
    $type(min(1  , 2  , 3)); // type: Int  , output: variadic ints
    $type(min(1.0, 2.0, 3)); // type: Float, output: variadic floats
  }
  
  inline extern overload static function min(a:Int, b:Int):Int
  {
    trace("2 ints");
    return a < b ? a : b;
  }
  
  inline extern overload static function min(...args:Int):Int
  {
    trace("variadic ints");
    return minVInt(args.toArray());
  }
  
  static function minVInt(args:Array<Int>):Int
  {
    var result = args[0];
    for (arg in args)
    {
      if (result > arg)
        result = arg;
    }
    return result;
  }
  
  inline extern overload static function min(a:Float, b:Float):Float
  {
    trace("2 floats");
    return a < b ? a : b;
  }
  
  inline extern overload static function min(...args:Float):Float
  {
    trace("variadic floats");
    return minVFloat(args.toArray());
  }
  
  static function minVFloat(args:Array<Float>):Float
  {
    var result = args[0];
    for (arg in args)
    {
      if (result > arg)
        result = arg;
    }
    return result;
  }
}

Also note that your generic implementation fails on min(1, 2.0); for some reason

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants