The IEEE 754:2008 spec lists a number of required operations. We should expose the missing operations to be more compliant and to give users the greatest flexibility when writing their applications.
NOTE: This does not represent all missing operations, but rather a smaller batch of operations that should be reasonable to review. The full set of missing operations is covered in https://github.com/dotnet/corefx/issues/31901
public partial static class Math
{
public static double BitIncrement(double); // IEEE `nextUp`, C `nextafter` - The smallest value such that `result > x`
public static double BitDecrement(double); // IEEE `nextDown` - The smallest value such that `result < x`
public static double MaxMagnitude(double, double); // IEEE `minNumMag` - `x` if `Abs(x) > Abs(y)`; `y` if `Abs(y) > Abs(x)`; otherwise `Max(x, y)`
public static double MinMagnitude(double, double); // IEEE `maxNumMag` - `x` if `Abs(x) < Abs(y)`; `y` if `Abs(y) < Abs(x)`; otherwise `Min(x, y)`
public static int ILogB(double); // IEEE `logB`, C `ilogb` - Equivalent to `(int)Math.Log2(x)`
public static double ScaleB(double, int); // IEEE `scaleB`, C `scalbn` - Equivalent to `x * 2^n`
public static double Log2(double); // IEEE `logB`, C `logb` or `log2`
public static double ScaleB(double, double); // IEEE `scaleB`, C `scalbn` - Equivalent to `x * 2^n`
public static double FusedMultiplyAdd(double, double, double); // IEEE `fusedMultiplyAdd`, C `fma`
public static double CopySign(double, double); // IEEE `copySign`, C `copysign` - Exposed internally as `Math.copysign`
}
public partial static class MathF
{
public static float BitIncrement(float); // IEEE `nextUp`, C `nextafterf` - The smallest value such that `result > x`
public static float BitDecrement(float); // IEEE `nextDown` - The smallest value such that `result < x`
public static float MaxMagnitude(float, float); // IEEE `minNumMag` - `x` if `Abs(x) > Abs(y)`; `y` if `Abs(y) > Abs(x)`; otherwise `Max(x, y)`
public static float MinMagnitude(float, float); // IEEE `maxNumMag` - `x` if `Abs(x) < Abs(y)`; `y` if `Abs(y) < Abs(x)`; otherwise `Min(x, y)`
public static int ILogB(float); // IEEE `logB`, C `ilogbf` - Equivalent to `(int)MathF.Log2(x)`
public static float ScaleB(float, int); // IEEE `scaleB`, C `scalbnf` - Equivalent to `x * 2^n`
public static float Log2(float); // IEEE `logB`, C `logbf` or `log2f`
public static float ScaleB(float, float); // IEEE `scaleB`, C `scalbnf` - Equivalent to `x * 2^n`
public static float FusedMultiplyAdd(float, float, float); // IEEE `fusedMultiplyAdd`, C `fmaf`
public static float CopySign(float, float); // IEEE `copySign`, C `copysignf` - Exposed internally as `MathF.copysign`
}
FusedMultiplyAdd support has been heavily requested (although mostly in adding runtime support for automatically performing the optimization).
CopySign is used heavily by many low-level floating point algorithms (including our managed implementations for several Math functions)
NextValue and PreviousValue are generally useful, since there is no "increment"/"decrement" operation (which may be better names) and you must currently use BitConverter
ILog2 and Scale2 are also generally useful for implementing low-level floating point algorithms, where you may need to do various floating-point format tricks
CC. @eerhardt, @danmosemsft
Some minor feedback:
What is the point of MaxMagnitude and MinMagnitude? That operation doesn't sound very common to me (but I could be wrong) and can be easily expressed with the existing API.
The purpose is to provide an efficient way to do Math.Min(Math.Abs(x), Math.Abs(y)) or Math.Max(Math.Abs(x), Math.Abs(y)), but as a single operation.
The primary use-case (to my knowledge) is to ensure that a list of values are sorted so-as to minimize floating-point rounding errors when operating on a list where order would not matter for "normal" math rules.
As an example, compute the sum of 50000, and 10k entries of -0.000001f.
If you start with 50000, your result will be 50000. But if you start with the smallest magnitude, you get 49999.99 (which is the "more accurate" result).
Hi, I'm new on this project, but this seems easy enough. Can I take a stab at it?
Sure thing.
As a pointer, this probably requires nearly identical changes to https://github.com/dotnet/coreclr/pull/15456 (but for the respective new APIs).
Feel free to ping me (either here, on our Gitter Channel, etc) if you have any questions/comments/concerns 😄
Thanks. I'm just having some trouble finding the right solution in corefx. I see a System.Numerics.Vector, but no System.Numerics
Never mind, got it
@mhall1, are you still working on this? (no rush if you are, I just want to ensure it is still taken by someone)
Yes, I am. I've just been busy with work lately.
On Fri, Oct 5, 2018, 1:51 AM Tanner Gooding, notifications@github.com
wrote:
@mhall1 https://github.com/mhall1, are you still working on this? (no
rush if you are, I just want to ensure it is still taken by someone)—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/31903#issuecomment-427253711,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AJtD0ZqjsJjVkuPi-tCOIIRTBi5sAc_Cks5uhvNfgaJpZM4WIvlE
.
I'm sorry, but it doesn't look like I'll be able to do this one after
all... Please go ahead and reassign it.
On Fri, Oct 5, 2018, 10:13 AM Michael Hall, mhall1@ualberta.ca wrote:
Yes, I am. I've just been busy with work lately.
On Fri, Oct 5, 2018, 1:51 AM Tanner Gooding, notifications@github.com
wrote:@mhall1 https://github.com/mhall1, are you still working on this? (no
rush if you are, I just want to ensure it is still taken by someone)—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/31903#issuecomment-427253711,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AJtD0ZqjsJjVkuPi-tCOIIRTBi5sAc_Cks5uhvNfgaJpZM4WIvlE
.
That's alright. Thanks for the heads up @mhall1
@tannergooding did API review prefer Ilog2 over ILog2? In your comments you have the latter, in the API listing and the PR the formre. If the i is for int then presumably it should be ILog2?
Review and the exact casing conversation is here: https://youtu.be/hLbCfJSPIaI?t=5400. It was determined that Ilog (capital I, lowercase L) was the right casing to use here.
Although I hear capitalization brought up, the discussion seemed to be about whether it should be called something else. @terrajobst just for the avoidance of doubt, are you OK with a lower case l? That basically means we think that ilog (or ilog2) is one word - or we are breaking convention.
Edited the original post to clarify the casing of ILog and to fix the comment on MaxMagnitude and MinMagnitude
Most helpful comment
Video
Some minor feedback: