Is there an easy, efficient and correct (i.e. not involving conversions to/from double) way to do floored integer division (like e.g. Python offers) in C#.
In other words, an efficient version of the following, that does not suffer from long/double conversion losses.
(long)(Math.Floor((double) a / b))
or does one have to implement it oneself, like e.g.
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;
}
*) Although the C# 4 spec of the Division operator leaves it open whether OverflowException is raised inside unchecked, in reality it does throw (on my system) and the Visual Studio .NET 2003 version even mandated it throw:
If the left operand is the smallest representable int or long value and the right operand is –1, [..] System.OverflowException is always thrown in this situation, regardless of whether the operation occurs in a checked or an unchecked context.
Edit
The crossed out statements about checked and unchecked are all nice and well, but checked is in fact only a compile time concept, so whether my function should wrap around or throw is up to me anyway, regardless of whether code calling the function is inside checked or not.
You can try this:
if (((a < 0) ^ (b < 0)) && (a % b != 0))
{
return (a/b - 1);
}
else
{
return (a/b);
}
Edit (after some discussions in comments below):
Without using if-else, I would go like this:
return (a/b - Convert.ToInt32(((a < 0) ^ (b < 0)) && (a % b != 0)));
Note: Convert.ToIn32(bool value) also needs a jump, see implemention of the method:
return value? Boolean.True: Boolean.False;
Theoretically, it is not possible 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. (Range of long is –9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.)
The way it works in any sane programming language (one that follows our normal order of operations) is that -1.0/3.0 is equivalent to -(1.0/3.0) which is -0.3333.... So if you want that converted to an int, it's really the cast/floor operator you need to think about, not the division. As such, if you want this behavior, you must use (int)Math.Floor(a/b), or custom code.
You don't need to implement this yourself, the Math class provides a builtin method for doing Euclidean division: Math.DivRem()
The only downside is that you have to provide an assignable variable for the remainder:
long remainder;
long quotient = Math.DivRem(a, b, out remainder);
Related
I've been presented what I think is an ANSI C statement but I don't understand what it is doing or if it is even valid.
x = (y == 4) * 12 + (y == 5) * 24;
Can anyone help me understand what this statement does in terms of C# (which I actually understand).
Thanks
Historically, C did not have a boolean type.* Comparison operators returned either 0 or 1, type int. Any int value (as well as other types) could be interpreted in boolean context, where 0 means false and any other value means true.
C# treats int and bool as completely separate types. The most direct C# equivalent is
x = (y == 4 ? 1 : 0) * 12 + (y == 5 ? 1 : 0) * 24;
Which can of course be improved greatly further.
* Typically, "ANSI C" is intended to refer to the original version of C, even though later versions of C have been adopted by ANSI too. Those later versions do add a boolean type, but the comparison operators still return int values. Similarly, integers in boolean contexts are still allowed as well. They do not change anything relevant to your question.
This is definitely wrong in C#. Both expressions, y==4 and y==5 are evaluated as a boolean. That being said, how can you define the multiplication between a boolean and an integer? This expression is not correct in C#.
I would say that you could try the following:
x = (y == 4 ? 1 : 0) * 12 + (y == 5 ? 1 : 0) * 24;
In the above expression we use the ternary operator, whose logic is quite simple it the expression evaluates to true then return the result after the question mark. Otherwise it returns the value after the :. So if y is equals to 4, then (y == 4 ? 1 : 0) evaluates to 1. Otherwise, it returns 0.
The above solution is based on that hvd mentioned below in his comment, that == returns either 0 or 1 in C.
Is it possible to re-write the following so that it doesn't contain any conditional statements? I'm thinking there might be some clever trick using something like bitwise operations?
int a = // some value
int b = // some other value between 0 and max int
if(b >= 3)
{
return a + 1;
}
else
{
return a;
}
EDIT: to be clear, I'm not looking for a generic way of removing conditionals. I'm looking for a trick to remove the conditionals from this very specific code. Think of it as an academic puzzle.
To give an example, one way to remove conditionals (which happens to yield perf gains in some situations) is to precompute a lookup table and index into that with b instead. In this particular case this is tricky because b could be a very large number. Is there another way?
Here you go
return a - ((2 - b) >> 31);
Explanation:
r = 2 - b, < 0 (i.e. high bit set) for b >= 3
r >> 31, = -1 for b >= 3, 0 otherwise
uint a = // some value
uint b = // some other value between 0 and max int
bool c = b & 0xFFFC
return a + Convert.ToInt32(c);
The fastest will probably be as bitwise operations tend to be very fast
uint a = // some value
uint b = // some other value between 0 and max int
return (b & 0xFFFC) ? a+1 : a;
You could make it better by doing this:
int a = // some value
int b = // some other value between 0 and max int
return (b >= 3) ? (a+1) : a;
?: operator. (but yet it contains conditional statement.)
return b >= 3 ? a + 1 : a;
or
return a + (b >= 3 ? 1 : 0);
Is it possible to re-write the following so that it doesn't contain any conditional statements?
It is not possible to make it work out of no where. you must check this condition any way. There is no magic.
If you want to make your program faster by removing this condition then you picked wrong way. this is micro optimization.
I have tried to write a code for Fermat primality test, but apparently failed.
So if I understood well: if p is prime then ((a^p)-a)%p=0 where p%a!=0.
My code seems to be OK, therefore most likely I misunderstood the basics. What am I missing here?
private bool IsPrime(int candidate)
{
//checking if candidate = 0 || 1 || 2
int a = candidate + 1; //candidate can't be divisor of candidate+1
if ((Math.Pow(a, candidate) - a) % candidate == 0) return true;
return false;
}
Reading the wikipedia article on the Fermat primality test, You must choose an a that is less than the candidate you are testing, not more.
Furthermore, as MattW commented, testing only a single a won't give you a conclusive answer as to whether the candidate is prime. You must test many possible as before you can decide that a number is probably prime. And even then, some numbers may appear to be prime but actually be composite.
Your basic algorithm is correct, though you will have to use a larger data type than int if you want to do this for non-trivial numbers.
You should not implement the modular exponentiation in the way that you did, because the intermediate result is huge. Here is the square-and-multiply algorithm for modular exponentiation:
function powerMod(b, e, m)
x := 1
while e > 0
if e%2 == 1
x, e := (x*b)%m, e-1
else b, e := (b*b)%m, e//2
return x
As an example, 437^13 (mod 1741) = 819. If you use the algorithm shown above, no intermediate result will be greater than 1740 * 1740 = 3027600. But if you perform the exponentiation first, the intermediate result of 437^13 is 21196232792890476235164446315006597, which you probably want to avoid.
Even with all of that, the Fermat test is imperfect. There are some composite numbers, the Carmichael numbers, that will always report prime no matter what witness you choose. Look for the Miller-Rabin test if you want something that will work better. I modestly recommend this essay on Programming with Prime Numbers at my blog.
You are dealing with very large numbers, and trying to store them in doubles, which is only 64 bits.
The double will do the best it can to hold your number, but you are going to loose some accuracy.
An alternative approach:
Remember that the mod operator can be applied multiple times, and still give the same result.
So, to avoid getting massive numbers you could apply the mod operator during the calculation of your power.
Something like:
private bool IsPrime(int candidate)
{
//checking if candidate = 0 || 1 || 2
int a = candidate - 1; //candidate can't be divisor of candidate - 1
int result = 1;
for(int i = 0; i < candidate; i++)
{
result = result * a;
//Notice that without the following line,
//this method is essentially the same as your own.
//All this line does is keeps the numbers small and manageable.
result = result % candidate;
}
result -= a;
return result == 0;
}
I was looking for an efficient approach for calculating ab (say a = 2 and b = 50). To start things up, I decided to take a look at the implementation of Math.Pow() function. But in .NET Reflector, all I found was this:
[MethodImpl(MethodImplOptions.InternalCall), SecuritySafeCritical]
public static extern double Pow(double x, double y);
What are some of the resources wherein I can see as what's going on inside when I call Math.Pow() function?
MethodImplOptions.InternalCall
That means that the method is actually implemented in the CLR, written in C++. The just-in-time compiler consults a table with internally implemented methods and compiles the call to the C++ function directly.
Having a look at the code requires the source code for the CLR. You can get that from the SSCLI20 distribution. It was written around the .NET 2.0 time frame, I've found the low-level implementations, like Math.Pow() to be still largely accurate for later versions of the CLR.
The lookup table is located in clr/src/vm/ecall.cpp. The section that's relevant to Math.Pow() looks like this:
FCFuncStart(gMathFuncs)
FCIntrinsic("Sin", COMDouble::Sin, CORINFO_INTRINSIC_Sin)
FCIntrinsic("Cos", COMDouble::Cos, CORINFO_INTRINSIC_Cos)
FCIntrinsic("Sqrt", COMDouble::Sqrt, CORINFO_INTRINSIC_Sqrt)
FCIntrinsic("Round", COMDouble::Round, CORINFO_INTRINSIC_Round)
FCIntrinsicSig("Abs", &gsig_SM_Flt_RetFlt, COMDouble::AbsFlt, CORINFO_INTRINSIC_Abs)
FCIntrinsicSig("Abs", &gsig_SM_Dbl_RetDbl, COMDouble::AbsDbl, CORINFO_INTRINSIC_Abs)
FCFuncElement("Exp", COMDouble::Exp)
FCFuncElement("Pow", COMDouble::Pow)
// etc..
FCFuncEnd()
Searching for "COMDouble" takes you to clr/src/classlibnative/float/comfloat.cpp. I'll spare you the code, just have a look for yourself. It basically checks for corner cases, then calls the CRT's version of pow().
The only other implementation detail that's interesting is the FCIntrinsic macro in the table. That's a hint that the jitter may implement the function as an intrinsic. In other words, substitute the function call with a floating point machine code instruction. Which is not the case for Pow(), there is no FPU instruction for it. But certainly for the other simple operations. Notable is that this can make floating point math in C# substantially faster than the same code in C++, check this answer for the reason why.
By the way, the source code for the CRT is also available if you have the full version of Visual Studio vc/crt/src directory. You'll hit the wall on pow() though, Microsoft purchased that code from Intel. Doing a better job than the Intel engineers is unlikely. Although my high-school book's identity was twice as fast when I tried it:
public static double FasterPow(double x, double y) {
return Math.Exp(y * Math.Log(x));
}
But not a true substitute because it accumulates error from 3 floating point operations and doesn't deal with the weirdo domain problems that Pow() has. Like 0^0 and -Infinity raised to any power.
Hans Passant's answer is great, but I would like to add that if b is an integer, then a^b can be computed very efficiently with binary decomposition. Here's a modified version from Henry Warren's Hacker's Delight:
public static int iexp(int a, uint b) {
int y = 1;
while(true) {
if ((b & 1) != 0) y = a*y;
b = b >> 1;
if (b == 0) return y;
a *= a;
}
}
He notes that this operation is optimal (does the minimum number of arithmetic or logical operations) for all b < 15. Also there is no known solution to the general problem of finding an optimal sequence of factors to compute a^b for any b other than an extensive search. It's an NP-Hard problem. So basically that means that the binary decomposition is as good as it gets.
If freely available C version of pow is any indication, it does not look like anything you would expect. It would not be of much help to you to find the .NET version, because the problem that you are solving (i.e. the one with integers) is orders of magnitudes simpler, and can be solved in a few lines of C# code with the exponentiation by squaring algorithm.
Going through the answers, learned a lot about behind-the-scene calculations:
I've tried some workarounds on a coding platform which has an extensive test coverage cases, and found a very effective way doing it(Solution 3):
public double MyPow(double x, int n) {
double res = 1;
/* Solution 1: iterative : TLE(Time Limit Exceeded)
double res = 1;
var len = n > 0 ? n : -n;
for(var i = 0; i < len; ++i)
res *= x;
return n > 0 ? res : 1 / res;
*/
/* Solution 2: recursive => stackoverflow exception
if(x == 0) return n > 0 ? 0 : 1 / x;
if(n == 1) return x;
return n > 0 ? x * MyPow(x, n - 1) : (1/x) * MyPow(1/x, -n);
*/
//Solution 3:
if (n == 0) return 1;
var half = MyPow(x, n / 2);
if (n % 2 == 0)
return half * half;
else if (n > 0)
return half * half * x;
else
return half * half / x;
/* Solution 4: bitwise=> TLE(Time Limit Exceeded)
var b = n > 0 ? n : -n;
while(true) {
if ((b & 1) != 0)
res *= x;
b = b >> 1;
if (b == 0) break;
x *= x;
}
return n > 0 ? res : 1 / res;
*/
}
Answer that is accepted on Leetcode:
public class Solution {
public double MyPow(double x, int n) {
if(n==0) return 1;
long abs = Math.Abs((long)n);
var result = pow(x, abs);
return n > 0 ? result : 1/result;
}
double pow(double x, long n){
if(n == 1) return x;
var result = pow(x, n/2);
result = result * result * (n%2 == 1? x : 1);
return result;
}
}
I have 2 convertor methods as below:
private const decimal MaxValidValue = 99.99m;
public decimal ConvertABToC(decimal a, decimal b)
{
return a * b;
}
public void ConvertCtoAB(decimal c, ref decimal a, ref decimal b)
{
if (c > MaxValidValue*MaxValidValue)
{
throw new ApplicationException();
}
if (c <= MaxValidValue)
{
a = 1.00m;
b = c;
}
else
{
// need to introduce some logic or assumptions here
}
}
There are 3 important things to know:
1) The a and b variables are in the range of 0.00 to 99.99 therefore c can't have a value greater than 99.99*99.99
2) the a, b and c must not have more than 2 decimal precession e.g. a = 99.123 would be invalid.
3) you can use rounding if you'd need to as long as decimal.Round(a * b, 2) == c.
4) combinations like (1, 3), (3, 1), (2, 2), (1, 4), (0.5, 8) or even (0.25, 16) are all valid; it doesn't matter as long as c would be the product of a and b.
How would you complete the implementation of ConvertCtoAB?
Many thanks,
Multiply C by 10,000. Then factor this number into its prime factors. Then find a partition of the prime factors into two sets such that the product of the numbers in each set is less than 10,000. If such a partition can be found, then return these two products divided by 100 as A and B. Otherwise, add one to the number and try again.
For example, if C=100.07, then the factors are 2, 2, 5, 5, 10007. Because one of the products must include the factor 10007, which is a prime number, the first condition can never be satisfied. So we try again with 1000701 = 3*3*3*13*2851. This time, we can partition the number, and we have A=3.51 and B=28.51 as a possible solution.
You can do this at most 99 times. If you need 100 or more, than the input value cannot have been generated from ConvertABToC.
This only guarantees that the result of ConvertCtoAB, when fed back into ConvertABtoC will produce the same C, not the other way around. It appears to violate rule #3, but then elsewhere the question is about rounding.
If no rounding at all is allowed, then one should stop and report infeasibility after trying the original 10000*C.
I've deleted my previous answer, as I don't believe it was helpful any more, as the question's changed so much over time.
Here's what I understand the question to be:
You are given an input (c) of type decimal such that:
0 <= c <= 99.99m * 99.99m
c has at most two decimal places (i.e. c == decimal.Round(c, 2))
You are required to find to decimal values a and b such that:
Each of a and b are in the range [0, 99.99m]
Each of a and b have at most two decimal places
decimal.Round(a * b, 2) == c
My answer is that it's still not possible for all values of c. Counterexample: c = 9997.50
The highest possible values of a and b (99.99m each) gives decimal.Round(a * b, 2) == 9998.00, so that fails with a product which is too high.
Now if you keep a as high as it can be, and reduce b as little as possible, we get a=99.99m, b=99.98m - and now decimal.Round(a * b, 2) == 9997.00, so that fails with a product which is too low.
There is no way of getting any product between those two values - we've perturbed our first attempt by as small an amount as possible. Therefore there are no values for a and b satisfying the problem.
(I'm anticipating a new rule being introduced to cope with this, as that seems to be the way this question is going...)
Skeet's idea to treat the interval as itself * 100 makes everything so much clearer...
The problem is indeed without a complete solution. It asks you to create a bijective function f : A x B -> C,
where A = B = {0 ... 9999} and C = {0 ... 9999*9999 }
9999*9999 = 9998001; plus the 0, that gives a cardinality of 99,980,002.
A X B has a cardinality of 100,000,000.
A bijective function over finite sets can't be defined when the domain and codomain have different cardinalities. There will always be at most 19,998 values of c whose (a, b) breakdown will have more than one solution.
Going back on the original interval definition: the closest you can get to a proper function is something like:
public decimal Ab2C(decimal a, decimal b)
{
if(a != 99.99 and a != 99.98)
return a*100 + b;
return (100-a)*100 + b; // for instance;
}
In this case, values for a between 0.02 to 99.97 will give unique results; a = 0.00 or 99.99 will be identical, likewise for a = 0.01 or 99.98. there is NO possible discrimination between these two values.
public void C2AB(decimal c, out decimal a, out decimal b)
{
// todo: sanity checks.
if (c <= 99.99) // either a = 0.00, or a = 99.99; and b = c.
{
b = c;
a = 0.00;
return;
}
if (c <= 2*99.99)
{
b = c - 99.99;
a = 0.01; // or 9.98.
return;
}
a = c / 100;
b = c % 100;
}
}