I would like to write a method in Objective-C that will result in a text string 'a:b:c:d'. I have four UISteppers (their values are displayed in a label each). I would like the ratio of those four numbers to display in their lowest integer form, including if some are 0.
Eg. a=6, b=4, c=0, d=0
Textstring = 3:2:0:0
I have found various ways of finding the greatest common divisor including http://macscripter.net/viewtopic.php?id=35759. However, I'm really new to iOS, this is my first app after Hello World, and the maths functions and even declaring a method, defining it and calling it are still a mystery.
Can you help out?
I settled for a method that takes the label values and alters the ratio label:
- (void)CalculateRatio {
int temp;
int PRBCs = [self.labelPRBCs.text integerValue];
int FFP = [self.labelFFP.text integerValue];
int u = PRBCs;
int v = FFP;
while (v != 0) {
temp = u % v;
u = v;
v = temp;
}
int PRBCratio = PRBCs / u;
int FFPratio = FFP / u;
double Plateletratio = [self.labelPlatelets.text doubleValue] / u;
double Cryoratio = [self.labelCryo.text doubleValue] / u;
NSString *returnValue = [NSString stringWithFormat:#"%d : %d : %.1lf : %.1lf", PRBCratio, FFPratio, Plateletratio, Cryoratio];
self.calculatedRatio.text = returnValue;
}
If you can see some syntactical errors, ways to improve this, I'd be happy to hear them.
Cheers.
Related
I've looked up some formulas relating to finding the distance a point and a line. On this page, I used example 14
http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
I have a method that has turned into this:
+(bool) checkPointNearBetweenPointsWithPointA:(CGPoint)pointA withPointB:(CGPoint)pointB withPointC:(CGPoint)pointC withLimit:(float)limit {
float A = pointB.x - pointA.x;
float B = pointA.y - pointC.y;
float C = pointA.x - pointC.x;
float D = pointB.y - pointA.y;
float dividend = fabs( A * B ) - ( C * D );
float divisor = sqrt(pow(A,2) + pow(D,2));
float distanceBetweenPointAndLine = dividend / divisor;
if(distanceBetweenPointAndLine < limit){
NSLog(#"distanceBetweenPointAndLine = %f",distanceBetweenPointAndLine);
return YES;
}
return NO;
}
The problem is that it still returns YES if I'm passed point B, if the line segment is drawn like B----A. Other screwed up things happen to depending on which angle the line is drawn. Just wondering if I need to consider anything else if testing to see if a point is near a finite line. Most examples I see online deal with lines of infinite length.
try my code below. line is considered to exist between points A & B (regardless of how you draw it B->A or A->B ) and point C is the point in consideration to measure the distance.
+ (bool) checkPointNearBetweenPointsWithPointA:(CGPoint)pointA
withPointB:(CGPoint)pointB
withPointC:(CGPoint)pointC
withLimit:(float)limit
{
CGFloat slopeLine = atan((pointB.y-pointA.y)/(pointB.x-pointA.x) );
CGFloat slopePointToPointA = -1 *atan((pointC.y-pointA.y)/(pointC.x-pointA.x));
CGFloat innerAngle = slopeLine + slopePointToPointA;
CGFloat distanceAC = sqrtf(pow(pointC.y-pointA.y,2) + pow(pointC.x-pointA.x,2));
CGFloat distanceBetweenPointAndLine = fabs(distanceAC * sin(innerAngle));
NSLog(#"distanceBetweenPointAndLine = %f",distanceBetweenPointAndLine);
NSLog(#"is exceeding limit ? %#",distanceBetweenPointAndLine > limit ? #"YES":#"NO");
if(distanceBetweenPointAndLine < limit)
{
return YES;
}
return NO;
}
i am not sure about my english, but i need to get the unit digit of an integer.
WITHOUT complex algorithm but with some API or another trick.
for example :
int a= 53;
int b=76;
this i add because i almost always dont "meet the quality standards" to post! its drive me crazy! please , fix it ! it took me 10 shoots to post this,and other issue also.
i need to get a=3 and b=6 in a simple smart way.
same about the other digit.
thanks a lot .
here is how to split the number into parts
int unitDigit = a % 10; //is 3
int tens= (a - unitDigit)/10; //is 53-3=50 /10 =5
You're looking for % operator.
a=a%10;//divides 'a' by 10, assigns remainder to 'a'
WARNING
here is how to divine the number into parts
int unitDigit = a % 10; //is 3
int tens= (a - unitDigit)/10; //is 53-3=50 /10 =5
this answer is totally incorrect. It may work only in a number of cases. For example try to get the first digit of 503 via this way
It seems the simplest answer (but not very good in performance):
int a = ...;
int digit = [[[NSString stringWithFormat:#"%d", a] substringToIndex:1] intValue]; //or use substringWithRange to get ANY digit
Modulo operator will help you (as units digit is a reminder when number is divided by 10):
int unitDigit = a % 10;
The following code "gets" the digits of a given number and counts how many of them divide the number exactly.
int findDigits(long long N){
int count = 0;
long long newN = N;
while(newN) // kinda like a right shift
{
int div = newN % 10;
if (div != 0)
if (N % div == 0) count++;
newN = newN / 10;
}
return count;
}
I did make algorithm for creating Bézier Curve with Objective-C and Cocos2D. Here is my code
-(int)factorial:(int)x{
int sum=1;
int i;
if(x == 0){
return 1;
}else{
for(i=1;i<x;i++){
sum = sum*i;
}
return sum;
}
}
-(int)binomialCoefficient:(int)n:(int)i{
int sum;
//NSLog([NSString stringWithFormat:#"fac n-i=%f\n", fach] );
sum = [self factorial:n]/([self factorial:i]*[self factorial:(n-i)]);
return sum;
}
-(float)convertT:(int)t{
return t*(0.001);
}
-(float)power:(float)a:(int)b{
int i;
float hasil=1;
for(i=0;i<b;i++){
hasil = hasil*a;
}
return hasil;
}
-(float)bernstein:(float)t:(int)n:(int)i{
float sum = 0;
sum = [self binomialCoefficient:n:i]*[self power:t :i]*[self power:(1-t) :(n-i)];
//NSLog([NSString stringWithFormat:#"yeah"]);
return sum;
}
and for implementation you just put an array of x and y and access it. For example to draw a single dot in control curve I did it like this
float myPx = px[i];
float myPy = py[i];
posx = posx+([self bernstein:theT :banyak-1 :i]*myPx);
posy = posy+([self bernstein:theT :banyak-1 :i]*myPy);
Yes, this code doesn't give the perfect nice line, but I try to draw it dot by dot.
It works well, but the problem arise when I try to use 3 dots. The middle dot for curving the lines didn't behave like what I expected. For example if I put 3 dots in these coordinates:
a(100,200)
b(250,250)
c(500,200)
It didn't curving up but curving down. If I want to put it straight I have to put it all the way higher.
Am I do it wrong in syntax or data types? Or is it just my algorithm?
Thanks in advance
Best Regards
(sorry for my bad english)
The factorial loop should be
for ( i = 1 ; i <= x ; i++ )
instead of
for ( i = 1 ; i < x ; i++ )
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 am trying to increase the performance of the update(); function below. The numbers inside the mathNumber variable will come from an NSString created from a text field. Even though I'm using five numbers I would like it to be able to run any amount that the user inserts into a text field. What are some ways I could speed up the code in update(); with C and/or Objective-C? I also would like it to work on the Mac and iPhone.
typedef struct {
float *left;
float *right;
float *equals;
int operation;
} MathVariable;
#define MULTIPLY 1
#define DIVIDE 2
#define ADD 3
#define SUBTRACT 4
MathVariable *mathVariable;
float *mathPointer;
float newNumber;
void init();
void update();
float solution(float *left, float *right, int *operation);
void init()
{
float *mathNumber = (float *) malloc(sizeof(float) * 9);
mathNumber[0] =-1.0;
mathNumber[1] =-2.0;
mathNumber[2] = 3.0;
mathNumber[3] = 4.0;
mathNumber[4] = 5.0;
mathNumber[5] = 0.0;
mathNumber[6] = 0.0;
mathNumber[7] = 0.0;
mathNumber[8] = 0.0;
mathVariable = (MathVariable *) malloc(sizeof(MathVariable) * 4);
mathVariable[0].equals = &mathPointer[5];
mathVariable[0].left = &mathPointer[2];
mathVariable[0].operation = MULTIPLY;
mathVariable[0].right = &mathPointer[3];
mathVariable[1].equals = &mathPointer[6];
mathVariable[1].left = &mathPointer[1];
mathVariable[1].operation = SUBTRACT;
mathVariable[1].right = &mathPointer[5];
mathVariable[2].equals = &mathPointer[7];
mathVariable[2].left = &mathPointer[0];
mathVariable[2].operation = ADD;
mathVariable[2].right = &mathPointer[6];
mathVariable[3].equals = &mathPointer[8];
mathVariable[3].left = &mathPointer[7];
mathVariable[3].operation = MULTIPLY;
mathVariable[3].right = &mathPointer[4];
return self;
}
// This is updated with a timer
void update()
{
int i;
for (i = 0; i < 4; i++)
{
*mathVariable[i].equals = solution(mathVariable[i].left, mathVariable[i].right, &mathVariable[i].operation);
}
// Below is the equivalent of: newNumber = (-1.0 + (-2.0 - 3.0 * 4.0)) * 5.0;
// newNumber should equal -75
newNumber = mathPointer[8];
}
float solution(float *left, float *right, int *operation)
{
if ((*operation) == MULTIPLY)
{
return (*left) * (*right);
}
else if ((*operation) == DIVIDE)
{
return (*left) / (*right);
}
else if ((*operation) == ADD)
{
return (*left) + (*right);
}
else if ((*operation) == SUBTRACT)
{
return (*left) - (*right);
}
else
{
return 0.0;
}
}
EDIT:
I first must say thank you for all of your kind posts. This is the first forum I've gotten people that don't tell me I'm a complete idiot. Sorry about the return self; I didn't realize this was an objective-C forum too (thus why I hastily used C). I have my own parser which is slow but I'm not concerned with its speed. All I want is to speed up the update() function since it slows everything down and 90% of the objects use it. Also, I'm try to get it to work faster with iOS devices since I can't compile anything in the text boxes. If you have any other advice on making update() faster I thank you.
Thanks again,
Jonathan
EDIT 2:
Well I got it to run faster by changing it from:
int i;
for (i = 0; i < 4; i++)
{
*mathVariable[i].equals = solution(*mathVariable[i].left, *mathVariable[i].right, mathVariable[i].operation);
}
To:
*mathVariable[0].equals = solution(*mathVariable[0].left, *mathVariable[0].right, mathVariable[0].operation);
*mathVariable[1].equals = solution(*mathVariable[1].left, *mathVariable[1].right, mathVariable[1].operation);
*mathVariable[2].equals = solution(*mathVariable[2].left, *mathVariable[2].right, mathVariable[2].operation);
*mathVariable[3].equals = solution(*mathVariable[3].left, *mathVariable[3].right, mathVariable[3].operation);
Is there any other way to increment it as fast as the preloaded numbers in the array like above?
Your code is a mix of styles, and contains some unwarranted uses of pointers (e.g. when passing operation to solution). It is unclear why you are passing the floats by reference, but maybe you intend that these change be changed and the expression reevaluated?
Below are some changes both to tidy and incidentally speed it up - the cost of any of this is not high and you may be guilt of premature optimization. As #Dave commented there are libraries to do parsing for you, but if you're targeting simple math expressions an operator precedence stack-based parser/evaluator is easy enough to code.
Suggestion 1: use enum - cleaner:
typedef enum { MULTIPLY, DIVIDE, ADD, SUBTRACT } BinaryOp;
typedef struct
{
float *left;
float *right;
float *equals;
BinaryOp operation;
} MathVariable;
Suggestion 2: use switch - cleaner and probably faster as well:
float solution(float left, float right, int operation)
{
switch(operation)
{
case MULTIPLY:
return left * right;
case DIVIDE:
return left / right;
case ADD:
return left + right;
case SUBTRACT:
return left - right;
default:
return 0.0;
}
}
Note I also removed passing pointers, the call is now:
*mathVariable[i].equals = solution(*mathVariable[i].left,
*mathVariable[i].right,
mathVariable[i].operation);
Now an OO person will probably object (:-)) to the switch (or the if/else) and argue each node (your MathVariable) should be an instance which knows how to perform its own operation. A C person might suggest you use function pointers in the node so they can perform their own operation. All this is design and you'll have to figure that out yourself.