I am making a calculator on C#.
I have to use float because, when I divide numbers, I get an answer less than 0.
but, I want the calculator to begin the new calculation with the answer i already got, So i wrote:
a = Convert.ToInt64(answer);
but, it doesn't help, it converts the answer to int64 too.
I think, I will be able to do with pointers, but I don't know how.
So how can I copy the value of answer to 'a' (the Input), without converting answer?
Int64 a; //1st Input
Int64 b; //2nd Input
float answer;
char d;
bool pressed;
private void button11_Click(object sender, EventArgs e)
{
if (d == '+') answer = a + b;
if (d == '-') answer = a - b;
if (d == '*') answer = a * b;
if (d == '/') answer = a / b;
textBox1.Text = a.ToString() + d + b.ToString() + '=' +answer.ToString();
a = Convert.ToInt64(answer);
b = 0;
}
sorry, for the lack of the whole source code, if anybody want's me to add them too just tell me :)
Couple of observations that may help:
Your inputs probably shouldn't be Int64 in the first place, as it is unlikely the user will work only in whole numbers, especially once they start using division.
Your answer and your inputs should be the same type, this will remove your casting issues.
Float is imprecise and may not be the best option. If you need better accuracy than Float can allow, you may try Decimal. (if you are unaware of the limitations of floating point arithmetic, Google for it)
First off guys, he's not asking how to make a calculator, he's just asking for help on a specific problem, I think that's what SO is supposed to be about.
You are on the right track, just needs some adjustments.
Operations
You most likely don't need Int64, you are probably looking for float or double. So here is a simple example:
float a = 1.0f;
float b = 2.0f;
float answer = a / b;
Here the answer would be 0.5, if a and b were integers the answer would be 0. If either one (or both) are float or double then the answer will be a decimal number.
If Statement
While we are at it, your if statement can be improved by making it an if-else:
if (d == '+') answer = a + b;
else if (d == '-') answer = a - b;
else if (d == '*') answer = a * b;
else if (d == '/') answer = a / b;
Why? Because d is only going to be one of those strings (+, -, *, /). With if-else, once a case is true the rest of the if's are skipped. With your code, even if d is +, the other three if statements are still checked.
Two options to consider:
Do only integer division.
Use floating point variable types for both input and output.
Related
To clarify first:
2^3 = 8. That's equivalent to 2*2*2. Easy.
2^4 = 16. That's equivalent to 2*2*2*2. Also easy.
2^3.5 = 11.313708... Er, that's not so easy to grok.
Want I want is a simple algorithm which most clearly shows how 2^3.5 = 11.313708. It should preferably not use any functions apart from the basic addition, subtract, multiply, or divide operators.
The code certainly doesn't have to be fast, nor does it necessarily need to be short (though that would help). Don't worry, it can be approximate to a given user-specified accuracy (which should also be part of the algorithm). I'm hoping there will be a binary chop/search type thing going on, as that's pretty simple to grok.
So far I've found this, but the top answer is far from simple to understand on a conceptual level.
The more answers the merrier, so I can try to understand different ways of attacking the problem.
My language preference for the answer would be C#/C/C++/Java, or pseudocode for all I care.
Ok, let's implement pow(x, y) using only binary searches, addition and multiplication.
Driving y below 1
First, take this out of the way:
pow(x, y) == pow(x*x, y/2)
pow(x, y) == 1/pow(x, -y)
This is important to handle negative exponents and drive y below 1, where things start getting interesting. This reduces the problem to finding pow(x, y) where 0<y<1.
Implementing sqrt
In this answer I assume you know how to perform sqrt. I know sqrt(x) = x^(1/2), but it is easy to implement it just using a binary search to find y = sqrt(x) using y*y=x search function, e.g.:
#define EPS 1e-8
double sqrt2(double x) {
double a = 0, b = x>1 ? x : 1;
while(abs(a-b) > EPS) {
double y = (a+b)/2;
if (y*y > x) b = y; else a = y;
}
return a;
}
Finding the answer
The rationale is that every number below 1 can be approximated as a sum of fractions 1/2^x:
0.875 = 1/2 + 1/4 + 1/8
0.333333... = 1/4 + 1/16 + 1/64 + 1/256 + ...
If you find those fractions, you actually find that:
x^0.875 = x^(1/2+1/4+1/8) = x^(1/2) * x^(1/4) * x^(1/8)
That ultimately leads to
sqrt(x) * sqrt(sqrt(x)) * sqrt(sqrt(sqrt(x)))
So, implementation (in C++)
#define EPS 1e-8
double pow2(double x, double y){
if (x < 0 and abs(round(y)-y) < EPS) {
return pow2(-x, y) * ((int)round(y)%2==1 ? -1 : 1);
} else if (y < 0) {
return 1/pow2(x, -y);
} else if(y > 1) {
return pow2(x * x, y / 2);
} else {
double fraction = 1;
double result = 1;
while(y > EPS) {
if (y >= fraction) {
y -= fraction;
result *= x;
}
fraction /= 2;
x = sqrt2(x);
}
return result;
}
}
Deriving ideas from the other excellent posts, I came up with my own implementation. The answer is based on the idea that base^(exponent*accuracy) = answer^accuracy. Given that we know the base, exponent and accuracy variables beforehand, we can perform a search (binary chop or whatever) so that the equation can be balanced by finding answer. We want the exponent in both sides of the equation to be an integer (otherwise we're back to square one), so we can make accuracy any size we like, and then round it to the nearest integer afterwards.
I've given two ways of doing it. The first is very slow, and will often produce extremely high numbers which won't work with most languages. On the other hand, it doesn't use log, and is simpler conceptually.
public double powSimple(double a, double b)
{
int accuracy = 10;
bool negExponent = b < 0;
b = Math.Abs(b);
bool ansMoreThanA = (a>1 && b>1) || (a<1 && b<1); // Example 0.5^2=0.25 so answer is lower than A.
double accuracy2 = 1.0 + 1.0 / accuracy;
double total = a;
for (int i = 1; i < accuracy* b; i++) total = total*a;
double t = a;
while (true) {
double t2 = t;
for(int i = 1; i < accuracy; i++) t2 = t2 * t; // Not even a binary search. We just hunt forwards by a certain increment
if((ansMoreThanA && t2 > total) || (!ansMoreThanA && t2 < total)) break;
if (ansMoreThanA) t *= accuracy2; else t /= accuracy2;
}
if (negExponent) t = 1 / t;
return t;
}
This one below is a little more involved as it uses log(). But it is much quicker and doesn't suffer from the super-high number problems as above.
public double powSimple2(double a, double b)
{
int accuracy = 1000000;
bool negExponent= b<0;
b = Math.Abs(b);
double accuracy2 = 1.0 + 1.0 / accuracy;
bool ansMoreThanA = (a>1 && b>1) || (a<1 && b<1); // Example 0.5^2=0.25 so answer is lower than A.
double total = Math.Log(a) * accuracy * b;
double t = a;
while (true) {
double t2 = Math.Log(t) * accuracy;
if ((ansMoreThanA && t2 > total) || (!ansMoreThanA && t2 < total)) break;
if (ansMoreThanA) t *= accuracy2; else t /= accuracy2;
}
if (negExponent) t = 1 / t;
return t;
}
You can verify that 2^3.5 = 11.313708 very easily: check that 11.313708^2 = (2^3.5)^2 = 2^7 = 128
I think the easiest way to understand the computation you would actually do for this would be to refresh your understanding of logarithms - one starting point would be http://en.wikipedia.org/wiki/Logarithm#Exponentiation.
If you really want to compute non-integer powers with minimal technology one way to do that would be to express them as fractions with denominator a power of two and then take lots of square roots. E.g. x^3.75 = x^3 * x^(1/2) * x^(1/4) then x^(1/2) = sqrt(x), x^(1/4) = sqrt(sqrt(x)) and so on.
Here is another approach, based on the idea of verifying a guess. Given y, you want to find x such that x^(a/b) = y, where a and b are integers. This equation implies that x^a = y^b. You can calculate y^b, since you know both numbers. You know a, so you can - as you originally suspected - use binary chop or perhaps some numerically more efficient algorithm to solve x^a = y^b for x by simply guessing x, computing x^a for this guess, comparing it with y^b, and then iteratively improving the guess.
Example: suppose we wish to find 2^0.878 by this method. Then set a = 439, b = 500, so we wish to find 2^(439/500). If we set x=2^(439/500) we have x^500 = 2^439, so compute 2^439 and (by binary chop or otherwise) find x such that x^500 = 2^439.
Most of it comes down to being able to invert the power operation.
In other words, the basic idea is that (for example) N2 should be basically the "opposite" of N1/2 so that if you do something like:
M = N2
L = M1/2
Then the result you get in L should be the same as the original value in N (ignoring any rounding and such).
Mathematically, that means that N1/2 is the same as sqrt(N), N1/3 is the cube root of N, and so on.
The next step after that would be something like N3/2. This is pretty much the same idea: the denominator is a root, and the numerator is a power, so N3/2 is the square root of the cube of N (or the cube of the square root of N--works out the same).
With decimals, we're just expressing a fraction in a slightly different form, so something like N3.14 can be viewed as N314/100--the hundredth root of N raised to the power 314.
As far as how you compute these: there are quite a few different ways, depending heavily on the compromise you prefer between complexity (chip area, if you're implementing it in hardware) and speed. The obvious way is to use a logarithm: AB = Log-1(Log(A)*B).
For a more restricted set of inputs, such as just finding the square root of N, you can often do better than that extremely general method though. For example, the binary reducing method is quite fast--implemented in software, it's still about the same speed as Intel's FSQRT instruction.
As stated in the comments, its not clear if you want a mathematical description of how fractional powers work, or an algorithm to calculate fractional powers.
I will assume the latter.
For almost all functions (like y = 2^x) there is a means of approximating the function using a thing called the Taylor Series http://en.wikipedia.org/wiki/Taylor_series. This approximates any reasonably behaved function as a polynomial, and polynomials can be calculated using only multiplication, division, addition and subtraction (all of which the CPU can do directly). If you calculate the Taylor series for y = 2^x and plug in x = 3.5 you will get 11.313...
This almost certainly not how exponentiation is actually done on your computer. There are many algorithms which run faster for different inputs. For example, if you calculate 2^3.5 using the Taylor series, then you would have to look at many terms to calculate it with any accuracy. However, the Taylor series will converge much faster for x = 0.5 than for x = 3.5. So one obvious improvement is to calculate 2^3.5 as 2^3 * 2^0.5, as 2^3 is easy to calculate directly. Modern exponentiation algorithms will use many, many tricks to speed up processing - but the principle is still much the same, approximate the exponentiation function as some infinite sum, and calculate as many terms as you need to get the accuracy that is required.
I want to make
BigInteger.ModPow(1/BigInteger, 2,5);
but 1/BigInteger always return 0, which causes, that the result is 0 too. I tried to look for some BigDecimal class for c# but I have found nothing. Is there any way how to count this even if there is no BigDecimal?
1/a is 0 for |a|>1, since BigIntegers use integer division where the fractional part of a division is ignored. I'm not sure what result you're expecting for this.
I assume you want to modular multiplicative inverse of a modulo m, and not a fractional number. This inverse exists iff a and m are co-prime, i.e. gcd(a, m) = 1.
The linked wikipedia page lists the two standard algorithms for calculating the modular multiplicative inverse:
Extended Euclidean algorithm, which works for arbitrary moduli
It's fast, but has input dependent runtime.
I don't have C# code at hand, but porting the pseudo code from wikipedia should be straight forward.
Using Euler's theorem:
This requires knowledge of φ(m) i.e. you need to know the prime factors of m. It's a popular choice when m is a prime and thus φ(m) = m-1 when it simply becomes . If you need constant runtime and you know φ(m), this is the way to go.
In C# this becomes BigInteger.ModPow(a, phiOfM-1, m)
The overload of the / operator chosen, is the following:
public static BigInteger operator /(
BigInteger dividend,
BigInteger divisor
)
See BigInteger.Division Operator. If the result is between 0 and 1 (which is likely when dividend is 1 as in your case), because the return value is an integer, 0 is returned, as you see.
What are you trying to do with the ModPow method? Do you realize that 2,5 are two arguments, two and five, not "two-point-five"? Is your intention "take square modulo 5"?
If you want floating-point division, you can use:
1.0 / (double)yourBigInt
Note the cast to double. This may lose precision and even "underflow" to zero if yourBigInt is too huge.
For example you need to get d in the next:
3*d = 1 (mod 9167368)
this is equally:
3*d = 1 + k * 9167368, where k = 1, 2, 3, ...
rewrite it:
d = (1 + k * 9167368)/3
Your d must be the integer with the lowest k.
Let's write the formula:
d = (1 + k * fi)/e
public static int MultiplicativeInverse(int e, int fi)
{
double result;
int k = 1;
while (true)
{
result = (1 + (k * fi)) / (double) e;
if ((Math.Round(result, 5) % 1) == 0) //integer
{
return (int)result;
}
else
{
k++;
}
}
}
let's test this code:
Assert.AreEqual(Helper.MultiplicativeInverse(3, 9167368), 6111579); // passed
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is floating point arithmetic in C# imprecise?
Why can't decimal numbers be represented exactly in binary?
I dont understand why, this formula works untill Scrap = 51, Rec Should be 17 but instead is 16.99.
Scrap = int.Parse(textBoxS.Text);
for (counter = 0; counter < Scrap; textBoxRec.Text = Rec.ToString() )
{
if (Rec == (int)Rec + 0.66)
{
Rec = (int)Rec + 1;
counter++;
}
else
{
Rec = Rec + 0.33;
counter++;
}
}
Comparing floating point numbers by == is never a good idea.
double d1 = 16.0 + 0.33 + 0.33
double d2 = 16.0 + 0.66
Then d1 != d2, since 0.33 does not have an exact representation as a double, since double is a binary floating point number and probably the double representation of 0.66 is different from two times the double representation of 0.33.
Use decimal.
And try to improve your code. Increasing the counter inside the loop and using the third position in the head of the for loop for a different purpose is horrible style, in my opinion.
I assume that Rec is double and its initial value is 0. than
Insted of
if (Rec == (int)Rec + 0.66)
use
if (Math.Abs(Rec-(int)Rec-0.66) < 0.001)
Simple solution: change Rec from double to decimal. If so, you also have to change 0.66 to 0.66m and 0.33 to 0.33m.
Rec == (int)Rec + 0.66 can be false even if numbers are "equal". It is related to floating point numbers binary representation. Floating point numbers must be compared in slightly different way:
if (Math.Abs(Rec - ((int) Rec + 0.66)) < epsilon) ...
where epsilon is some small value, in this case 0.1 will be enough.
I understand that floating point arithmetic as performed in modern computer systems is not always consistent with real arithmetic. I am trying to contrive a small C# program to demonstrate this. eg:
static void Main(string[] args)
{
double x = 0, y = 0;
x += 20013.8;
x += 20012.7;
y += 10016.4;
y += 30010.1;
Console.WriteLine("Result: "+ x + " " + y + " " + (x==y));
Console.Write("Press any key to continue . . . "); Console.ReadKey(true);
}
However, in this case, x and y are equal in the end.
Is it possible for me to demonstrate the inconsistency of floating point arithmetic using a program of similar complexity, and without using any really crazy numbers? I would like, if possible, to avoid mathematically correct values that go more than a few places beyond the decimal point.
double x = (0.1 * 3) / 3;
Console.WriteLine("x: {0}", x); // prints "x: 0.1"
Console.WriteLine("x == 0.1: {0}", x == 0.1); // prints "x == 0.1: False"
Remark: based on this don't make the assumption that floating point arithmetic is unreliable in .NET.
Here's an example based on a prior question that demonstrates float arithmetic not working out exactly as you would think.
float f = (13.45f * 20);
int x = (int)f;
int y = (int)(13.45f * 20);
Console.WriteLine(x == y);
In this case, false is printed to the screen. Why? Because of where the math is performed versus where the cast to int is happening. For x, the math is performed in one statement and stored to f, then it is being cast to an integer. For y, the value of the calculation is never stored before the cast. (In x, some precision is lost between the calculation and the cast, not the case for y.)
For an explanation behind what's specifically happening in float math, see this question/answer. Why differs floating-point precision in C# when separated by parantheses and when separated by statements?
My favourite demonstration boils down to
double d = 0.1;
d += 0.2;
d -= 0.3;
Console.WriteLine(d);
The output is not 0.
Try making it so the decimal is not .5.
Take a look at this article here
http://floating-point-gui.de/
try sum VERY big and VERY small number. small one will be consumed and result will be same as large number.
Try performing repeated operations on an irrational number (such as a square root) or very long length repeating fraction. You'll quickly see errors accumulate. For instance, compute 1000000*Sqrt(2) vs. Sqrt(2)+Sqrt(2)+...+Sqrt(2).
The simplest I can think of right now is this:
class Test
{
private static void Main()
{
double x = 0.0;
for (int i = 0; i < 10; ++i)
x += 0.1;
Console.WriteLine("x = {0}, expected x = {1}, x == 1.0 is {2}", x, 1.0, x == 1.0);
Console.WriteLine("Allowing for a small error: x == 1.0 is {0}", Math.Abs(x - 1.0) < 0.001);
}
}
I suggest that, if you're truly interested, you take a look any one of a number of pages that discuss floating point numbers, some in gory detail. You will soon realize that, in a computer, they're a compromise, trading off accuracy for range. If you are going to be writing programs that use them, you do need to understand their limitations and problems that can arise if you don't take care. It will be worth your time.
double is accurate to ~15 digits. You need more precision to really start hitting problems with only a few floating point operations.
When I try to take the N th root of a small number using C# I get a wrong number.
For example, when I try to take the third root of 1.07, I get 1, which is clearly not true.
Here is the exact code I am using to get the third root.
MessageBox.Show(Math.Pow(1.07,(1/3)).toString());
How do I solve this problem?
I would guess that this is a floating point arithmetic issue, but I don't know how to handle it.
C# is treating the 1 and the 3 as integers, you need to do the following:
Math.Pow(1.07,(1d/3d))
or
Math.Pow(1.07,(1.0/3.0))
It is actually interesting because the implicit widening conversion makes you make a mistake.
I'm pretty sure the "exact code" you give doesn't compile.
MessageBox.Show(Math.Pow(1.07,(1/3).toString()));
The call to toString is at the wrong nesting level, needs to be ToString, and (1/3) is integer division, which is probably the real problem you're having. (1/3) is 0 and anything to the zeroth power is 1. You need to use (1.0/3.0) or (1d/3d) or ...
First things first: if that's the exact code you're using, there's likely something wrong with your compiler :-)
MessageBox.Show(Math.Pow(1.07,(1/3).toString()));
will evaluate (1/3).toString() first then try and raise 1.07 to the power of that string.
I think you mean:
MessageBox.Show(Math.Pow(1.07,(1/3)).ToString());
As to the problem, (1/3) is being treated as an integer division returning 0 and n0 is 1 for all values of n.
You need to force it to a floating point division with something like 1.0/3.0.
This may help in case you have a real nth root precision problem, but my experiance is that the builtin Math.Pow(double, int) is more precise:
private static decimal NthRoot(decimal baseValue, int N)
{
if (N == 1)
return baseValue;
decimal deltaX;
decimal x = 1M;
do
{
deltaX = (baseValue / Pow(x, N - 1) - x) / N;
x = x + deltaX;
} while (Math.Abs(deltaX) > 0);
return x;
}
private static decimal Pow(decimal a, int b)
{
if (b == 0) return 1;
if (a == 0) return 0;
if (b == 1) return a;
if (b % 2 == 0)
return Pow(a * a, b / 2);
else if (b % 2 == 1)
return a * Pow(a * a, b / 2);
return 0;
}