I have some C# application:
double n = p * q;
double S = Math.Pow(M, d) % n;
In my situation, M==7, d==27, n = 55. I calculate it in the Windows default calculator, and get 28. But my application returns 14. Why?
double has a maximum of 16 digits of precision, but 7^27 is a 23-digit number, so you are losing precision in the exponentiation. Windows calculator supports 32 digits of precision for transcendental functions (like pow), so it can perform the calculation without a loss of precision.
You could use the mathematical fact that (a^b) % N is the same an ((a%n) ^ b) % n, but you're still raining a number greater then 2 to the 27th power which can't be precisely represented in a double.
Another option is to split the power into multiple exponents that can be represented in a double without a loss of precision:
7^27 = 7^9 * 7^9 * 7^9
7^27 % 55 = ((7^9) % 55 * (7^9) % 55 * (7^9) % 55) % 55
= (52 * 52 * 52) % 55
= 140,608 % 55
= 28
As D Stanley mentioned, double only has 16 digits of precision. You need to use BigInteger. Which is in .NET 4.5 and 4.6. You'll need to add a reference to System.Numerics
BigInteger test = BigInteger.Pow(7, 27) % 55;
Related
This simple calculation is returning zero, I can't figure it out:
decimal share = (18 / 58) * 100;
You are working with integers here. Try using decimals for all the numbers in your calculation.
decimal share = (18m / 58m) * 100m;
18 / 58 is an integer division, which results in 0.
If you want decimal division, you need to use decimal literals:
decimal share = (18m / 58m) * 100m;
Since some people are linking to this from pretty much any thread where the calculation result is a 0, I am adding this as a solution as not all the other answers apply to case scenarios.
The concept of needing to do calculations on various types in order to obtain that type as a result applies, however above only shows 'decimal' and uses it's short form such as 18m as one of the variables to be calculated.
// declare and define initial variables.
int x = 0;
int y = 100;
// set the value of 'x'
x = 44;
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0.
Console.WriteLine( (x / y).ToString() );
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0. The conversion to double happens
// after the calculation has been completed, so technically this results
// in 0.0
Console.WriteLine( ((double)(x / y)).ToString() );
// Results in 0.44 as the variables are cast prior to calculating
// into double which allows for fractions less than 1.
Console.WriteLine( ((double)x / (double)y).ToString() );
Because the numbers are integers and you perform integer division.
18 / 58 is 0 in integer division.
Whenever I encounter such situations, I just upcast the numerator.
double x = 12.0 / 23409;
decimal y = 12m / 24309;
Console.WriteLine($"x = {x} y = {y}");
double res= (firstIntVar * 100f / secondIntVar) / 100f;
when dividing numbers I use double or decimal , else I am getting 0 , with this code even if firstIntVar && secondIntVar are int it will return the expected answer
decimal share = (18 * 100)/58;
Solved: working perfectly with me
int a = 375;
int b = 699;
decimal ab = (decimal)a / b * 100;
This simple calculation is returning zero, I can't figure it out:
decimal share = (18 / 58) * 100;
You are working with integers here. Try using decimals for all the numbers in your calculation.
decimal share = (18m / 58m) * 100m;
18 / 58 is an integer division, which results in 0.
If you want decimal division, you need to use decimal literals:
decimal share = (18m / 58m) * 100m;
Since some people are linking to this from pretty much any thread where the calculation result is a 0, I am adding this as a solution as not all the other answers apply to case scenarios.
The concept of needing to do calculations on various types in order to obtain that type as a result applies, however above only shows 'decimal' and uses it's short form such as 18m as one of the variables to be calculated.
// declare and define initial variables.
int x = 0;
int y = 100;
// set the value of 'x'
x = 44;
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0.
Console.WriteLine( (x / y).ToString() );
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0. The conversion to double happens
// after the calculation has been completed, so technically this results
// in 0.0
Console.WriteLine( ((double)(x / y)).ToString() );
// Results in 0.44 as the variables are cast prior to calculating
// into double which allows for fractions less than 1.
Console.WriteLine( ((double)x / (double)y).ToString() );
Because the numbers are integers and you perform integer division.
18 / 58 is 0 in integer division.
Whenever I encounter such situations, I just upcast the numerator.
double x = 12.0 / 23409;
decimal y = 12m / 24309;
Console.WriteLine($"x = {x} y = {y}");
double res= (firstIntVar * 100f / secondIntVar) / 100f;
when dividing numbers I use double or decimal , else I am getting 0 , with this code even if firstIntVar && secondIntVar are int it will return the expected answer
decimal share = (18 * 100)/58;
Solved: working perfectly with me
int a = 375;
int b = 699;
decimal ab = (decimal)a / b * 100;
In order to create a floating point number from a decimal value, we need to have a sign bit, and exponent, and a mantissa.
Double precision uses 11 exponent bits, and 52 mantissa bits.
Let's say we want to store 0.3. We can find the mantissa by doing the following:
0.3 * 2 = 0.6 => 0
0.6 * 2 = 1.2 => 1
0.2 * 2 = 0.4 => 0
0.4 * 2 = 0.8 => 0
0.8 * 2 = 1.6 => 1
0.6 * 2 = 1.2 => 1
...
Answer:
01001100110011...
In C# I can do this with the following code:
double value = 0.3;
StringBuilder bitString = new StringBuilder();
for (int i = 0; i < 53; i++)
{
value *= 2;
if (value >= 1)
{
bitString.Append("1");
value--;
}
else
{
bitString.Append("0");
}
}
Is it possible to take an existing mantissa from a double, and continue this process to find further bits? I know this won't work for certain values, but what if I have an exact number like 0.123, and I know all the remaining digits are 0. 0.1230000000...
My code above seems to have a problem. Since I am using a double for my multiplication, I only have 15-17 digits of precision. It is possible during my multiply by 2 situation to be slightly off ending the number of bits I can accurately store. Is there away around this without needing a bigger type like System.Decimal?
The goal here is to end up with a bit string, that contains more than 53 bits of valid data.
This simple calculation is returning zero, I can't figure it out:
decimal share = (18 / 58) * 100;
You are working with integers here. Try using decimals for all the numbers in your calculation.
decimal share = (18m / 58m) * 100m;
18 / 58 is an integer division, which results in 0.
If you want decimal division, you need to use decimal literals:
decimal share = (18m / 58m) * 100m;
Since some people are linking to this from pretty much any thread where the calculation result is a 0, I am adding this as a solution as not all the other answers apply to case scenarios.
The concept of needing to do calculations on various types in order to obtain that type as a result applies, however above only shows 'decimal' and uses it's short form such as 18m as one of the variables to be calculated.
// declare and define initial variables.
int x = 0;
int y = 100;
// set the value of 'x'
x = 44;
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0.
Console.WriteLine( (x / y).ToString() );
// Results in 0 as the whole number 44 over the whole number 100 is a
// fraction less than 1, and thus is 0. The conversion to double happens
// after the calculation has been completed, so technically this results
// in 0.0
Console.WriteLine( ((double)(x / y)).ToString() );
// Results in 0.44 as the variables are cast prior to calculating
// into double which allows for fractions less than 1.
Console.WriteLine( ((double)x / (double)y).ToString() );
Because the numbers are integers and you perform integer division.
18 / 58 is 0 in integer division.
Whenever I encounter such situations, I just upcast the numerator.
double x = 12.0 / 23409;
decimal y = 12m / 24309;
Console.WriteLine($"x = {x} y = {y}");
double res= (firstIntVar * 100f / secondIntVar) / 100f;
when dividing numbers I use double or decimal , else I am getting 0 , with this code even if firstIntVar && secondIntVar are int it will return the expected answer
decimal share = (18 * 100)/58;
Solved: working perfectly with me
int a = 375;
int b = 699;
decimal ab = (decimal)a / b * 100;
I'm experimenting with negative-base number systems, and I use Excel to play with and check my calculations.
I notice that there are differences in C# vs. Excel. Why does C# return a different result than Excel?
For example:
C#: 146 % -3 = 2
Excel: mod(146, -3) = -1
Let's suppose we have four integers: x, y, q, and r such that
q = x / y
r = x - q * y
I hope that it makes sense that the quotient and remainder must have this relationship.
Now we come to the difference between C# and Excel. The difference is actually in the division, not the remainder. When computing the quotient of two integers, C# rounds towards zero, and Excel rounds down. That is, in C# 8 / -3 is -2, and in excel, INT(8 / -3) is -3.
From that fact you can deduce why the remainders are different.
As the Wikipedia article says, a modulo operation is dividend % divisor == remainder. The problem comes when either of the operands are negative values. At that point, the naive mathematical definition breaks down and the result becomes implementation-dependent.
In Excel, the mod operator always returns a result with the same sign as the divisor. Mathematically, the quotient used in the modulo operation is rounded downwards (towards −∞). In pseudo-code:
quotient = floor(dividend / divisor)
mod = dividend - (divisor * quotient)
Therefore, for 146 and -3:
quotient = -49 // floor(146 / -3)
mod = -1 // 146 - (-3 * -49) == 146 - 147
In C#, it is the opposite: the result always has the same sign as the dividend. This is because the quotient is truncated toward 0. In pseudo-code:
quotient = truncate(dividend / divisor)
mod = dividend - (divisor * quotient)
Therefore:
quotient = -48 // truncate(146 / -3)
mod = 2 // 146 - (-3 * -48) == 146 - 144