It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
Please see the formulæ below.
It's the solution to a circle chord problem where A is the arc length and C is the chord length.
I want to find the Radius r.
The formula below uses factorials and powers etc which I don't know how to express in Objective C.
Can somebody help by converting the formula into Objective C language?
a = A² – C²
b = -2A^4/4!
c = 2A^6/6!
d = -2A^8/8!
//Let:
f = c/a-b²/3a²
g = d/a+2b³/27a³-bc/3a²
x = cuberoot(-g/2 + sqrt(g²/4+f³/27)) – cuberoot(g/2 + sqrt(g²/4+f³/27)) - b/3a
r = sqrt(x)
This should work:
double factorial(int x)
{
double result = 1;
for (x = x; x > 0; x--)
{
result *= x;
}
return result;
}
...
int A = 20;
int C = 25;
double a = A*A - C*C;
double b = -2.0*pow(A, 4.0)/factorial(4);
double c = 2.0*pow(A, 6.0)/factorial(6);
double d = -2.0*pow(A, 8.0)/factorial(8);
//Let:
double f = c/a-(b*b)/(3.0*(a*a));
double g = d/a + 2.0*pow(b, 3.0)/(27.0*pow(a, 3.0))-(b*c)/(3.0*a*a);
double x = pow(-g/2.0 + sqrt(g*g/4.0+pow(f, 3.0)/27.0), 1.0/3.0) - pow(g/2.0 + sqrt(g*g/4.0+pow(f, 3.0)/27.0), 1.0/3.0) - b/(3.0*a);
double r = sqrt(x);
The header is <math.h>. You square by multiplying a factor by itself; you cube by multiplying a factor by itself twice. The factorials are constants; you precalculate them, or let the computer do so:
enum { factorial_3 = 1 * 2 * 3 }; // Not needed, but an example
enum { factorial_3 = 3 * factorial_2 }; // Alternative technique
The function sqrt() gives you the square root. If it is available, then cbrt() from C99 gives you a cube root. When it isn't available, you can use pow() instead. If the notation A^4, A^6 and A^8 is equivalent to A4, A6, A8, then those are easily handled as multiplications.
You can assemble the bits and pieces using this information.
For exponents, you can use math.h(which you'll need to import)'s pow(float base, float exponent) function. Then for factorials, you'll have to create one yourself. The following function should work (I didn't try it out yet).
long factorial(int number)
{
long numb = 1;
for (int i=1;i<=number;i++)
{
numb*=i;
}
return numb;
}
However, be aware that it's very easy to get too huge numbers with factorials, so use long long (or even malloc if necessary) if you need to get the factorial of a large number.
Related
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I have been reading a programming book and it wants me to write a program listing a table of the first 10 factorial numbers. I have been trying for the past 45 minutes, but can't come up with a solution. Please Help! I'm pretty sure the program involves using loops.
The easiest way to calculate the factorial is with a recursive function or a simple loop as shown below. I'll leave it up to you to figure out how to list the information in a table as there are lots of ways to skin that cat.
Header File Function Declaration:
-(int)factorialRecursive:(int)operand;
-(int)factorialLoop:(int)operand;
Implementation File Function Declaration:
-(int)factorialRecursive:(int)operand
{
if( operand == 1 || operand == 0) {
return(1);
} else if( operand < 0 ) {
return(-1);
}
return( operand * [self factorialRecursive:operand-1] );
}
-(int)factorialLoop:(int)operand
{
if( operand == 1 || operand == 0) {
return(1);
} else if( operand < 0 ) {
return(-1);
}
int factorial = 1;
for(int i = operand; i > 1; i-- ) {
factorial *= i;
}
return( factorial );
}
Sample Call:
int factNumber = 10;
NSLog(#"%d! = %d",factNumber,[self factorialRecursive:factNumber]);
NSLog(#"%d! = %d",factNumber,[self factorialLoop:factNumber]);
I have this equation
double x = ((newCount/allCount)/.8)*5.0;
newCount is a double with value 0
allCount is a double with value 0
the result of x is -nan(0x8000000000000)
why this happens and how to check this value in objective c to assign default value for it
You are diving by zero. You can check for it using:
isnan(x)
The problem is that the denominator (allCount) is 0; dividing by zero is not allowed and the answer is not a number. The simplest thing you could do is to test for that before doing the division:
if (allCount != 0) {
x = ((newCount/allCount)/.8)*5.0
} else {
x = defaultValue;
}
There are more complicated ways using C's floating point environment and testing for the FE_DIVBYZERO exception, but while that's standard it's rarely used and therefore potentially more difficult for a later reader of the code to comprehend.
allCount is a 0, thus you just divided by 0 (which is impossible if you didn't know..) So before you assign x, just make sure that allCount is not 0 first.
if (allCount != 0)
double x = ((newCount/allCount)/.8)*5.0;
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
In need some help with this little programming .. I just got 3 errors ..
:'(
**[
#include <stdio.h>
int main (void)
{
char A , B , C , D , E , F;
float id1[]; <<< *Definition of variable with array type needs an explicit size or an initializer*
float grade[]; <<< *Definition of variable with array type needs an explicit size or an initializer*
float marks[]; <<< *Definition of variable with array type needs an explicit size or an initializer*
float average;
float num1, kk=0;
/********* Jami, Abdulrahman *********/
printf("Enter The Student ID: ");
scanf("%d", &num1);
for (kk=0; kk<num1; kk++);
{
scanf("%d", &id1[kk]);
scanf("%d", &grade[kk]);
}
for (kk=0; kk<num1; kk++);
{
if (grade [kk]>85 &grade [kk]<=100);
A=A+1;
if (grade [kk]>70 &grade [kk]<85);
B=B+1;
if (grade [kk]>55 &grade [kk]<70);
C=C+1;
if (grade [kk]>40 &grade [kk]<55);
D=D+1;
if (grade [kk]>25 &grade [kk]<40);
E=E+1;
if (grade [kk]>=0 &grade [kk]<25);
F=F+1;
}
/********* Jami, Abdulrahman *********/
float aveerage;
float avrg, sum, lk;
sum = sum + marks[lk];
average = sum / num1;
for (lk=0; lk<num1; lk++);
return average;
}
]**
You must give it a size like 3 (it can be any integer though) or something:
For example:
float id1[];
//Should be:
float id1[3]; //Or whatever number you want.
Or you can do:
float id1[] = { 0, 0, 0 }; //To get the same effect as id1[3] where they would all be initialized at zero.
Or even better:
float id1[3] = { }; //Initialize all 3 elements to zero.
The error tells you that you need to set a size on these arrays. Try defining them as float myArray[maxMarks];
Of course maxMarks is the maximal number of marks, not the highest mark...
Try something like
float *id1;
or
float id1[100];
or
float id1[] = { 1.0, 2.0, 3.3, 7.2, 9.1, 1.5, 4.1 };
The [] can only be empty if you initialize the array with values. if you use float *id1;, you'll have to malloc() memory to use it. The other two are real arrays.
As other said: read the error messages you get and think about what they could mean.
In Xcode /Objective-C for the iPhone.
I have a float with the value 0.00004876544. How would I get it to display to two decimal places after the first significant number?
For example, 0.00004876544 would read 0.000049.
I didn't run this through a compiler to double-check it, but here's the basic jist of the algorithm (converted from the answer to this question):
-(float) round:(float)num toSignificantFigures:(int)n {
if(num == 0) {
return 0;
}
double d = ceil(log10(num < 0 ? -num: num));
int power = n - (int) d;
double magnitude = pow(10, power);
long shifted = round(num*magnitude);
return shifted/magnitude;
}
The important thing to remember is that Objective-C is a superset of C, so anything that is valid in C is also valid in Objective-C. This method uses C functions defined in math.h.
I've inherited a Visual Studio/VB.Net numerical simulation project that has a likely inefficient calculation. Profiling indicates that the function is called a lot (1 million times plus) and spends about 50% of the overall calculation within this function. Here is the problematic portion
Result = (A * (E ^ C)) / (D ^ C * B) (where A-C are local double variables and D & E global double variables)
Result is then compared to a threshold which might have additional improvements as well, but I'll leave them another day
any thoughts or help would be appreciated
Steve
The exponent operator (Math.Pow) isn't very fast, there is no dedicated CPU instruction for calculating it. You mentioned that D and E are global variables. That offers a glimmer of hope to get it faster, if you can isolate their changes. Rewriting the equation using logarithms:
log(r) = log((a x e^c) / (b x d^c))
= log(a x e^c) - log (b x d^c)
= log(a) + log(e^c) - log(b) - log(d^c)
= log(a) + c*log(e) - log(b) - c*log(d)
= log(a) - log(b) + c x (log(e) - log(d))
result = exp(r)
Which provides this function to calculate the result:
Function calculate(ByVal a As Double, ByVal b As Double, ByVal c As Double, ByVal d As Double, ByVal e As Double) As Double
Dim logRes = Math.Log(a) - Math.Log(b) + c * (Math.Log(e) - Math.Log(d))
Return Math.Exp(logRes)
End Function
I timed it with the StopWatch class, it is exactly as fast as your original expression. Not a coincidence of course. You'll get ahead by somehow being able to pre-calculate the Math.Log(e) - Math.Log(d) term.
One easy speed up is that
Result = (A/B) * (E/D)^C
At least you are doing one less exponent.
Depending on what C is, there might be faster ways. Like if C is a small integer.
edit:
adding proof to show this is faster
public static void main(String[] args) {
StopWatch sw = new StopWatch();
float e = 1.123F;
float d = 4.456F;
float c = 453;
sw.start();
int max = 5000;
double result = 0;
for (int a = 1; a < max; a++) {
for (float b = 1; b < max; b++) {
result = (a * (Math.pow(e, c))) / (Math.pow(d, c) * b);
}
}
sw.split();
System.out.println("slow: " + sw.getSplitTime() + " result: " + result);
sw.stop();
sw.reset();
sw.start();
result = 0;
for (int a = 1; a < max; a++) {
for (float b = 1; b < max; b++) {
result = a / b * Math.pow(e/d, c);
}
}
sw.split();
System.out.println("fast: " + sw.getSplitTime() + " result: " + result);
sw.stop();
sw.reset();
}
This is the output
slow: 26062 result: 7.077390271736578E-272
fast: 12661 result: 7.077392136525382E-272
There is some skew in the numbers. I would think that the faster version is more exact (but that's just a feeling since i can't think of exactly why).
Well done for profiling. I would also check that A-C are different on every call. In other words, is it possible the caller is actually calculating the same value over and over again? If so, change it so it caches the answer.
For Math.Floor() function, visit:
http://bitsbyta.blogspot.com/2010/12/math-floor-function-vbnet.html
All functions of math library in vb.net is available at:
http://www.bitsbyta.blogspot.com/