Floating whole division

Is there a simple, efficient, and correct (i.e. non-conversion to / from double) way to make a gender-separated integer (e.g. Python suggests ) in C #.

In other words, an effective version of the next that does not suffer from long / double conversion loss.

(long)(Math.Floor((double) a / b)) 

or you need to implement it, for example,

 static long FlooredIntDiv(long a, long b) { if (a < 0) { if (b > 0) return (a - b + 1) / b; // if (a == long.MinValue && b == -1) // see *) below // throw new OverflowException(); } else if (a > 0) { if (b < 0) return (a - b - 1) / b; } return a / b; } 

*) Despite the fact that the C # 4 specification of the department operator leaves it open , whether an OverflowException thrown inside unchecked , it actually throws (to my system) and the version of Visual Studio .NET 2003 even gave it the opportunity to throw:

If the left operand is the smallest representable value of int or long, and the right operand is -1, [..] System.OverflowException always occurs in this situation, regardless of whether the operation occurs in a checked or uncontrolled context,

Strike>

Edit

The strikethrough statements about checked and unchecked are fine and good, but checked is actually just a compile-time concept , so no matter if my function should wrap or throw, I don’t care whether the code that calls this function inside checked or not.

0
source share
2 answers

You can try the following:

 if (((a < 0) ^ (b < 0)) && (a % b != 0)) { return (a/b - 1); } else { return (a/b); } 

Edit (after some discussion in the comments below):

Without using if-else, I would do the following:

 return (a/b - Convert.ToInt32(((a < 0) ^ (b < 0)) && (a % b != 0))); 

Note: Convert.ToIn32(bool value) also requires a jump, see the implementation of the method:

 return value? Boolean.True: Boolean.False; 

It is theoretically impossible to calculate the division for a = long.MinValue and b = -1L , since the expected result is a/b = abs(long.MinValue) = long.MaxValue + 1 > long.MaxValue . (The long range is from –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 .)

+1
source

The way it works in any normal programming language (which follows our usual order of operations) is that -1.0/3.0 equivalent to -(1.0/3.0) , which is -0.3333... Therefore, if you want the converted to int, this is really a cast / floor operator that you need to think about, not division. Thus, if you want this behavior, you must use (int)Math.Floor(a/b) or your own code.

0
source

Source: https://habr.com/ru/post/1211675/


All Articles