I'm trying to create a function to calculate the mean, max, min and standard deviation of a set of numbers.
I'd like it to work like the UIColor function - (void)getRed:green:blue:alpha. i.e. you pass in the four float values and the function then overwrites them.
I'm struggling to find the right syntax for it.
My function is...
- (void)calculateStatsAverage:(float)average
standardDeviation:(float)standardDeviation
minimum:(float)minimum
maximum:(float)maximum
{
//pseudo code
average = total / count;
minimum = min value;
etc...
//
}
The problem I'm getting is getting the values out again.
If I change the function to use float* (which is what the UIColor function does) then my calculations don't like assigning the variables.
To simplify...
Imagine these functions. The first is called from elsewhere.
- (void)runThisFunction
{
float someOutputValue = 0.0;
[self changeTheValue:someOutputValue];
NSLog(#"The value is %f", someOutputValue);
}
- (void)changeTheValue:(float)value
{
value = 10.0;
}
I'd like this code to output "The value is 10.0"; But at the moment I'm getting "The value is 0.0".
Please could you show me how to write these two functions. From there I'll be able to work out the rest.
Thanks
- (void)passByRefMethod:(float *)ptr
{
*ptr = MYVALUE;
}
Sorry for formatting, typed on phone. Hope this helps!
This technique is often called pass by reference, and it's part of C so you can use that to search for more info.
Your NSLog is displaying the value of the local variable 'someOutputValue', which has been assigned to be 0.0.
Your 'changeTheValue' method has no effect.
The following code may help,
- (void)runThisFunction
{
float someOutputValue = 0.0;
float resultOfCalc = [self calcTheValue:someOutputValue];
NSLog(#"The value is %f", resultOfCalc);
}
- (float) changeTheValue:(float)value // note that this method returns a float
{
float newValue;
// do whatever calc is appropriate, e.g.
newValue = value + 10.0;
return newValue; // pass back the result of calc
}
This will output,
The value is 10.
Related
I have no idea why this code does not work. The whole idea about it is to make the value bigger until it's bigger than score.
if(score > height && rocketlaunch == false)
{
#try
{
height = [self makebigger:height];
}
#catch (NSException *exception)
{
height = height + 4000;
}
upgradeRocket.center = CGPointMake((rand()%200), -50);
rocketlaunch = true;
}
-(int)makebigger:(int)heightnr {
heightnr = heightnr + (1000 * rand() %5);
if(score > heightnr) {
[self makebigger:heightnr];
return heightnr;
} else {
return heightnr;
}
}
Does anyone know how to fix this? Or have a alternative way?
P.S.
The error displayed was:
Implicit conversion of int to id is disallowed with ARC
and
Incompatible integer to pointer conversion returning int from a function with result type id
Thank you in advance.
EDIT:
It works this way thank you very much :)
EDIT:
I got a new problem hard to solve:
this gives the error > tread 1 exc bad acces code = 2
change -makebigger:(int)heightnr to - (int)makebigger:(int)heightnr.
You have to specify the return type.
And you have to return something if the condition is true, too.
Until now I didn't even know it was possible to use no return type. But apparently it is.
Assuming score is an instance variable of type int then you have two errors in your code: first you must specify the return type of the method otherwise id is assumed; and second every path must return a value and your recursive call does not do this. Correcting those gives:
- (int)makebigger:(int)heightnr
{
heightnr = heightnr + (1000 * rand() %5);
if(score > heightnr)
return [self makebigger:heightnr];
else
return heightnr;
}
While this should work for simple value-based algorithms like this it is more usual to use iteration rather than recursion, as in:
- (int)makebigger:(int)heightnr
{
while (score > heightnr)
heightnr = heightnr + (1000 * rand() %5);
return heightnr;
}
I am going to take a guess that your "score" variable is an NSNumber. The compiler is complaining because you are trying to compare an NSNumber (object) to an int.
Try this:
if([score intValue] > heightnr)
I'm sort of a newbie--please don't hate.
The method compiles, but I'm not sure how to actually retrieve the float value (i.e. the distance between the two points) that the method returns (or should return rather).
-(float)findDistanceBetween:(Coordinate *)a and:(Coordinate *)b
{
//distance formula:
//sqrt( (x2 - x1)^2 + (y2 - y1)^2 )
float resultDistance;
resultDistance = sqrt( pow((b.latitude - a.latitude), 2) + pow((b.longitude - a.longitude), 2));
return resultDistance;
}
//Somewhere else...
float theDistanceBetween;
//Below is incorrect:
theDistanceBetween = [findDistanceBetween: location1 and: location2];
Thanks
So, if your error is that self is undeclared, that means that you are trying to send -findDistanceBetween:and: from outside the context of the class that declares it.
When you do something like [obj method], that demands a few things:
That obj is an instance of an Objective-C class.
That the class of obj implements -method.
So, if the receiver of your message is self, that means that:
You need to be within the context of a class's implementation for the self to be implicitly declared.
The class you're in needs to be the same one as implements -findDistanceBetween:and:.
Methods are not just a shiny replacement for functions that can be called in any context. They can be called on objects that implement them (technically not "called" in Smalltalk-like languages such as Objective-C, but that's for another time).
I suspect that you have larger design issues as well. What kind of object is -findDistanceBetween:and: meant to be sent to? If it is a utility method in a class that does something bigger, then it should be a class method (+findDistanceBetween:and:), since it does not need to know about any specific instance. If, however, it is a method on Coordinate, then it'd be better expressed as -findDistanceTo:, which would take a coordinate parameter. And then the implementation of that would compare the provided coordinate parameter with self.
findDistanceBetween:and: is an instance method; it's something a particular instance of your class can do.
So you'd call it like:
theDistanceBetween = [self findDistanceBetween: location1 and: location2];
Which means "send the message 'findDistanceBetween: location1 and: location2' to the object 'self', and store the result to theDistanceBetween". self just means the current object; it's an object sending a message to itself.
Is findDistanceBetween:and: defined in an #implementation block? Your code should look something like
// in the .h file
#interface MyClass : NSObject
// declaration of the method
- (float)findDistanceInBetween:(Coordinate *)a and:(Coordinate *)b;
#end
// in the .m file
#implementation MyClass
// definition of the method
- (float)findDistanceBetween:(Coordinate *)a and:(Coordinate *)b {
return sqrt(powf(a.x - b.x, 2.f) + powf(a.y - b.y, 2.f));
}
#end
// then somewhere else that needs to calculate the difference:
// (assume coord_a and coord_b already exist)
// create an instance of MyClass
MyClass *myInstance = [[MyClass alloc] init];
// send the `findDistanceBetween:and:` message to the instance
float distance = [myInstance findDistanceBetween:coord_a and:coord_b];
// when you're done with the instance, you need to clean up
[myInstance release];
It may make more sense to put these types of methods on the Coordinate class itself so you can just do something like:
Coordinate *coord_a = <get the coordinate from somewhere>;
Coordinate *coord_b = <get the coordinate from somewhere>;
float distance = [coord_a distanceFrom:coord_b];
float angle = [coord_a angleTo:coord_b];
Don't worry about anyone hating, we were all new at this once. :)
Try to add -(float)findDistanceBetween:(Coordinate *)a and:(Coordinate *)b; to your .h file
As mentioned by Ferruccio above latitude and longitude are in degrees and you method should be returning some form of distance. Below are some methods that will calculate distance as well as bearing between 2 CLLocationCoordinate2Ds.
- (double)degreeToRadian:(double)degree{
return (degree * (M_PI/180.0));
}
- (double)radianToDegree:(double)radian{
return (radian *(180.0/M_PI));
}
-(double) distanceFromCordinate:(CLLocationCoordinate2D)fromCoord to:(CLLocationCoordinate2D)toCoord {
double radiusOfEarth = 6371.0;
double fromLongitude, fromLatitude, toLongitude, toLatitude;
double _deltaLongitude, _deltaLatitude;
double a, c;
fromLongitude = [self degreeToRadian:fromCoord.longitude];
fromLatitude = [self degreeToRadian:fromCoord.latitude];
toLongitude = [self degreeToRadian:toCoord.longitude];
toLatitude = [self degreeToRadian:toCoord.latitude];
_deltaLongitude = toLongitude - fromLongitude;
_deltaLatitude = toLatitude - fromLatitude;
a = (sin(_deltaLatitude/2) * sin(_deltaLatitude/2)) + ( cos(fromLatitude) * cos(toLatitude) * (sin(_deltaLongitude/2) * sin(_deltaLongitude/2)) );
c = 2 * atan2( sqrt(a), sqrt(1-a));
return (radiusOfEarth * c);
}
- (double)bearingFromCordinate:(CLLocationCoordinate2D)fromCoord to:(CLLocationCoordinate2D)toCoord{
double fromLatitude, toLatitude;
double _deltaLongitude;
double x, y;
double bearing;
fromLatitude = [self degreeToRadian:fromCoord.latitude];
toLatitude = [self degreeToRadian:toCoord.latitude];
deltaLongitude = [self degreeToRadian:(toCoord.longitude - fromCoord.longitude)];
y = sin(deltaLongitude) * cos(toLatitude);
x = (cos(fromLatitude) * sin(toLatitude)) - (sin(fromLatitude) * cos(toLatitude) * cos(deltaLongitude));
bearing = atan2(y,x);
return fmod(([self radianToDegree:bearing] + 360.0), 360.0) ;
}
I'm really newbie developing iphone apps, and I got a question...
I would like to know how must I do to receive the var that my function returns.
Take a look:
-(void)myfunc{
float num1 = 2.50;
float num2 = 3.50;
//here is my doubt, how can I get the value that function returns?
float varreceived = [self getNumber:num1:num2];
}
//the function that receive the vars and returns a value
-(float)getNumber: (float)var1 :(float)var2 {
NSLog(#"1->%f",var1);
NSLog(#"2->%f",var2);
return 3.23;
}
I receive this error when I build:
"error: void value not ignored as it ought to be"
in this line:
float varreceived = [self getNumber:num1:num2];
Update:
Nop, I receive this error when I build:
"error: void value not ignored as it ought to be"
in this line:
float varreceived = [self getNumber:num1:num2];
Max:
then you probably declared the -(float)getNumber: (float)var1 :(float)var2 as -(void)getNumber: (float)var1 :(float)var2 in your header
HispaJavi:
Yeah!! this is the problem, I wrote "-(void)getNumber" in header! I changed it "-(float)getNumber" and it works!! thanks!!
Everything is OK. You'll receive 3.23
I really have no idea how this is done, it should be simple but i just cant get it
i have an IBAction and void and want to do this:
-(IBAction)pass{
int VariableX = 10;
[self getVar]; ---> send var to -(void)getVar
}
-(void)getVar{
get the VariableX
if(VariableX=10){
do something
}
}
declare getVar function to get one (integer) parameter:
// header
-(void)getVar:(int)varX;
// implementation
-(void)getVar:(int)varX{
if (varX == 10)
// do something
}
Then call it the following way:
-(IBAction)pass{
int VariableX = 10;
[self getVar:VariableX];
}
Generally the syntax of method declaration in objective-c is:
- (ReturnType) functionName:(1st parameter type)1stParameterName
2ndParameter:(2nd parameter type)2ndParameterName
etc
I'm writing an application that requires the user be in a quiet environment. To do this, I periodically check the power reading off the microphone. (I'm aware of the returned value being in dBFS or, in this case, a float in the interval [0, 1]. )
My problem is that the below code works just fine... except when it returns 18466064732283753157623808.00000. I see no NSLog output indicating AudioQueueGetProperty returning a failure. The weird value is always the mentioned value.
-(float)instantaneousPeakPower {
UInt32 dataSize = sizeof(AudioQueueLevelMeterState) * recordFormat.mChannelsPerFrame;
AudioQueueLevelMeterState *levels = (AudioQueueLevelMeterState*)malloc(dataSize);
OSStatus rc = AudioQueueGetProperty(audioQueue, kAudioQueueProperty_CurrentLevelMeter, levels, &dataSize);
if (rc) {
NSLog(#"NoiseLeveMeter>>takeSample - AudioQueueGetProperty(CurrentLevelMeter) returned %#", rc);
}
float channelAvg = 0;
for (int i = 0; i < recordFormat.mChannelsPerFrame; i++) {
channelAvg += levels[i].mPeakPower;
}
free(levels);
// This works because in this particular case one channel always has an mAveragePower of 0.
return channelAvg;
}
What gives? Does the bit pattern of the value perhaps give a clue?
Did you enabled audio level metering?
UInt32 trueValue = true;
AudioQueueSetProperty(audioQueue,kAudioQueueProperty_EnableLevelMetering,&trueValue,sizeof (UInt32));