Algorithm for max and min? (Objective-C) - objective-c

This is a part of a book I'm reading to learn Objective-C.
The following defines a macro called MAX that gives the maximum of two
values: #define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
And then there are some exercises in the book that asks the reader to define a macro (MIN) to find the minimum of two values and another that asks to define a macro called MAX3 that gives the maximum of 3 values. I think these two definitions will look similar to MAX, but I don't understand how the MAXformula finds the maximum value. I mean if I just did this
int limits = MAX (4,8)
It'll just assign limits the value of 8. What does that have to do with finding a variable's maximum value?

I think you are confusing value and variable. The macro example you listed expands to a comparison between two values and returns the greater of the two values (i.e. which is greater, a or b). So you are right, int limits = MAX(4,8) just assigns 8 to limits and has nothing to do with finding the maximum value you can store in limits.
The header limits.h defines many values like INT_MAX that will tell you information about the min/max values of variable types on your system.

To break it apart:
The declaration:
#define MAX(a,b)
If a is greater than b, use a else use b:
( ((a) > (b)) ? (a) : (b) )
Then to create a MIN expression, use a similar form:
#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
^
Then to create a MAX3 expression, you can combine them:
#define MAX3(a,b,c) ( MAX(a, MAX(b,c)) )
Specifically, this macro's intended to be used with scalars (C builtins) which can be compared using < or >. If you passed an objc variable, it would result in comparison of addresses and MAX would return the one with the higher address (it would be very rare if you actually wanted to compare addresses of objc instances).
Also note that this is the classic example of how macros can bite you. With macros, the preprocessor simply expands (textual copy/paste) the parameters in place, so: int limits = MAX (4,8) literally expands to int limits = (4 > 8 ? 4 : 8). If you write MAX(x,++y), then y will be incremented twice if y is greater than or equal to x because it expands to: int limits = (x > ++y ? x : ++y).

generally, you will use a MAX() or MIN() macro to get whichever is the higher/lower of a pair of variables, or of a variable and a constant, or even a pair of macro constants or other non-literal constant expressions. you generally won't supply 2 literal constants as you have done in your question.

Algorithm for max (Objective-C)
// get max value
- (float)maxValue:(NSArray *)arrValue
{
float maxValue = 0.0;
for (NSString *value in arrValue) {
float compareValue = [value floatValue];
if (compareValue > maxValue) {
maxValue = compareValue;
}
}
return maxValue;
}
NSArray *number=[NSArray arrayWithObjects:[NSNumber numberWithFloat:57.02], [NSNumber numberWithFloat:55.02], [NSNumber numberWithFloat:45.02], nil];
NSLog(#"%f", [self maxValue:number]);
result 57.020000

Related

Given no modulus or if even/odd function, how would one check for an odd or even number?

I have recently sat a computing exam in university in which we were never taught beforehand about the modulus function or any other check for odd/even function and we have no access to external documentation except our previous lecture notes. Is it possible to do this without these and how?
Bitwise AND (&)
Extract the last bit of the number using the bitwise AND operator. If the last bit is 1, then it's odd, else it's even. This is the simplest and most efficient way of testing it. Examples in some languages:
C / C++ / C#
bool is_even(int value) {
return (value & 1) == 0;
}
Java
public static boolean is_even(int value) {
return (value & 1) == 0;
}
Python
def is_even(value):
return (value & 1) == 0
I assume this is only for integer numbers as the concept of odd/even eludes me for floating point values.
For these integer numbers, the check of the Least Significant Bit (LSB) as proposed by Rotem is the most straightforward method, but there are many other ways to accomplish that.
For example, you could use the integer division operation as a test. This is one of the most basic operation which is implemented in virtually every platform. The result of an integer division is always another integer. For example:
>> x = int64( 13 ) ;
>> x / 2
ans =
7
Here I cast the value 13 as a int64 to make sure MATLAB treats the number as an integer instead of double data type.
Also here the result is actually rounded towards infinity to the next integral value. This is MATLAB specific implementation, other platform might round down but it does not matter for us as the only behavior we look for is the rounding, whichever way it goes. The rounding allow us to define the following behavior:
If a number is even: Dividing it by 2 will produce an exact result, such that if we multiply this result by 2, we obtain the original number.
If a number is odd: Dividing it by 2 will result in a rounded result, such that multiplying it by 2 will yield a different number than the original input.
Now you have the logic worked out, the code is pretty straightforward:
%% sample input
x = int64(42) ;
y = int64(43) ;
%% define the checking function
% uses only multiplication and division operator, no high level function
is_even = #(x) int64(x) == (int64(x)/2)*2 ;
And obvisouly, this will yield:
>> is_even(x)
ans =
1
>> is_even(y)
ans =
0
I found out from a fellow student how to solve this simplistically with maths instead of functions.
Using (-1)^n :
If n is odd then the outcome is -1
If n is even then the outcome is 1
This is some pretty out-of-the-box thinking, but it would be the only way to solve this without previous knowledge of complex functions including mod.

Get the most occuring number amongst several integers without using arrays

DISCLAIMER: Rather theoretical question here, not looking for a correct answere, just asking for some inspiration!
Consider this:
A function is called repetitively and returns integers based on seeds (the same seed returns the same integer). Your task is to find out which integer is returned most often. Easy enough, right?
But: You are not allowed to use arrays or fields to store return values of said function!
Example:
int mostFrequentNumber = 0;
int occurencesOfMostFrequentNumber = 0;
int iterations = 10000000;
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
int occurencesOfResult = magic();
if(occurencesOfResult > occurencesOfMostFrequentNumber)
{
mostFrequentNumber = result;
occurencesOfMostFrequentNumber = occurencesOfResult;
}
}
If getNumberFromSeed() returns 2,1,5,18,5,6 and 5 then mostFrequentNumber should be 5 and occurencesOfMostFrequentNumber should be 3 because 5 is returned 3 times.
I know this could easily be solved using a two-dimentional list to store results and occurences. But imagine for a minute that you can not use any kind of arrays, lists, dictionaries etc. (Maybe because the system that is running the code has such a limited memory, that you cannot store enough integers at once or because your prehistoric programming language has no concept of collections).
How would you find mostFrequentNumber and occurencesOfMostFrequentNumber? What does magic() do?? (Of cause you do not have to stick to the example code. Any ideas are welcome!)
EDIT: I should add that the integers returned by getNumber() should be calculated using a seed, so the same seed returns the same integer (i.e. int result = getNumber(5); this would always assign the same value to result)
Make an hypothesis: Assume that the distribution of integers is, e.g., Normal.
Start simple. Have two variables
. N the number of elements read so far
. M1 the average of said elements.
Initialize both variables to 0.
Every time you read a new value x update N to be N + 1 and M1 to be M1 + (x - M1)/N.
At the end M1 will equal the average of all values. If the distribution was Normal this value will have a high frequency.
Now improve the above. Add a third variable:
M2 the average of all (x - M1)^2 for all values of xread so far.
Initialize M2 to 0. Now get a small memory of say 10 elements or so. For every new value x that you read update N and M1 as above and M2 as:
M2 := M2 + (x - M1)^2 * (N - 1) / N
At every step M2 is the variance of the distribution and sqrt(M2) its standard deviation.
As you proceed remember the frequencies of only the values read so far whose distances to M1 are less than sqrt(M2). This requires the use of some additional array, however, the array will be very short compared to the high number of iterations you will run. This modification will allow you to guess better the most frequent value instead of simply answering the mean (or average) as above.
UPDATE
Given that this is about insights for inspiration there is plenty of room for considering and adapting the approach I've proposed to any particular situation. Here are some thoughts
When I say assume that the distribution is Normal you should think of it as: Given that the problem has no solution, let's see if there is some qualitative information I can use to decide what kind of distribution would the data have. Given that the algorithm is intended to find the most frequent number, it should be fine to assume that the distribution is not uniform. Let's try with Normal, LogNormal, etc. to see what can be found out (more on this below.)
If the game completely disallows the use of any array, then fine, keep track of only, say 10 numbers. This would allow you to count the occurrences of the 10 best candidates, which will give more confidence to your answer. In doing this choose your candidates around the theoretical most likely value according to the distribution of your hypothesis.
You cannot use arrays but perhaps you can read the sequence of numbers two or three times, not just once. In that case you can read it once to check whether you hypothesis about its distribution is good nor bad. For instance, if you compute not just the variance but the skewness and the kurtosis you will have more elements to check your hypothesis. For instance, if the first reading indicates that there is some bias, you could use a LogNormal distribution instead, etc.
Finally, in addition to providing the approximate answer you would be able to use the information collected during the reading to estimate an interval of confidence around your answer.
Alright, I found a decent solution myself:
int mostFrequentNumber = 0;
int occurencesOfMostFrequentNumber = 0;
int iterations = 10000000;
int maxNumber = -2147483647;
int minNumber = 2147483647;
//Step 1: Find the largest and smallest number that _can_ occur
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
if(result > maxNumber)
{
maxNumber = result;
}
if(result < minNumber)
{
minNumber = result;
}
}
//Step 2: for each possible number between minNumber and maxNumber, count occurences
for(int thisNumber = minNumber; thisNumber <= maxNumber; thisNumber++)
{
int occurenceOfThisNumber = 0;
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
if(result == thisNumber)
{
occurenceOfThisNumber++;
}
}
if(occurenceOfThisNumber > occurencesOfMostFrequentNumber)
{
occurencesOfMostFrequentNumber = occurenceOfThisNumber;
mostFrequentNumber = thisNumber;
}
}
I must admit, this may take a long time, depending on the smallest and largest possible. But it will work without using arrays.

Why do some C math expressions require constants to be explicitly marked as floats?

So I just found this bug in my code and I am wondering what rules I'm not understanding.
I have a float variable logDiff, that currently contains a very small number. I want to see if it's bigger than a constant expression (80% of a 12th). I read years ago in Code Complete to just leave calculated constants in their simplest form for readability, and the compiler (XCode 4.6.3) will inline them anyway. So I have,
if ( logDiff > 1/12 * .8 ) {
I'm assuming the .8 and the fraction all evaluates to the correct number. Looks legit:
(lldb) expr (float) 1/12 * .8
(double) $1 = 0.0666666686534882
(lldb) expr logDiff
(float) $2 = 0.000328541
But it always wrongly evaluates to true. Even when I mess with enclosing parens and stuff.
(lldb) expr logDiff > 1/12 * .8
(bool) $4 = true
(lldb) expr logDiff > (1/12 * .8)
(bool) $5 = true
(lldb) expr logDiff > (float)(1/12 * .8)
(bool) $6 = true
I found I have to explicitly spell at least one of them as floats to get the correct result,
(lldb) expr logDiff > (1.f/12.f * .8f)
(bool) $7 = false
(lldb) expr logDiff > (1/12.f * .8)
(bool) $8 = false
(lldb) expr logDiff > (1./12 * .8f)
(bool) $11 = false
(lldb) expr logDiff > (1./12 * .8)
(bool) $12 = false
but I recently read a popular style guide explicitly eschew these fancier numeric literals, apparently according to my assumption that the compiler would be smarter than me and Do What I Mean.
Should I always spell my numeric constants like 1.f if they might need to be a float? Sounds superstitious. Help me understand why and when it's necessary?
The expression 1/12 is an integer division. That means that the result will be truncated as zero.
When you do (float) 1/12 you cast the one as a float, and the whole expression becomes a floating point expression.
In C int/int gives an int. If you don't explicitly tell the compiler to convert at least one to a float, it will do the division and round down to the nearest int (in this case 0).
I note that the linked style guide actually says Avoid making numbers a specific type unless necessary. In this case it is needed as what you want is for the compiler to do some type conversions
An expression such as 1 / 4 is treated as integer division and hence has no decimal precision. In this specific case, the result will be 0. You can think of this as int / int implies int.
Should I always spell my numeric constants like 1.f if they might need to be a float? Sounds superstitious. Help me understand why and when it's necessary?
It's not superstitious, you are telling the compiler that these are type literals (floats as an example) and the compiler will treat all operations on them as such.
Moreover, you could cast an expression. Consider the following:
float result = ( float ) 1 / 4;
... I am casting 1 to be a float and hence the result of float / int will be float. See datatype operation precedence (or promotion).
That is simple. Per default, a numeric value is interpredted as an int.
There are math expresssions where that does not matter too much. But in case of divisions it can drive you crazy. (int) 1 / (int) 12 is not (float) 0.08333 but (int) 0.
1/12.0 would evaluate to (float) 0.83333.
Side note: When you go for float where you used int before there is one more trap waiting for you. That is when ever you compare values for equality.
float f = 12/12.0f;
if (f = 1) ... // this may not work out. Never expect a float to be of a specific value. They can vary slightly.
Better is:
if (abs(f - 1) < 0.0001) ... // this way yoru comparison is fuzzy enough for the variances that float values may come with.

finding the closest Int value from a set of int values in objective c

objective c math function question
I've got a x value that i'd like to compare to other values within a set, then determine which value from the set my x value is closest to.
For example, lets say i've got the ints 5, 10, 15, 20, 25.
What is the best way to determine which of these numbers is closest to 7?
int closestDistance = INT32_MAX;
int indexOfClosestDistance = -1;
int x = 7;
for (int i=0; i < [yourArray count]; i++)
{
int num = yourArray[i];
int diff = abs(num - x);
if (diff < closestDistance)
{
closestDistance = diff;
indexOfClosestDistance = i ;
}
}
Best of luck
Neither Objective-C nor Cocoa provides anything that solves this for you. You can store your ints in a plain old array of int, or you can wrap each one in an NSNumber and store the wrappers in an NSArray.
If you're going to probe the array many times, sort it once in advance, and then for each probe use a binary search (standard C function bsearch or Core Foundation's CFArrayBSearchValues or Cocoa's -[NSArray indexOfObject:inSortedRange:options:usingComparator:]) to find the nearest two elements. If you're only going to probe the array once or twice, just use a for loop, subtraction, abs, and MIN.
The easiest way is subtract the smaller number from the larger one. So you'd want to compare the two numbers first, then just do simple subtraction. So you'd see the 10-7 is 3 away, and 7-5 is only 2 away.

'while' Loop in Objective-C

The following program calculates and removes the remainder of a number, adds the total of the remainders calculated and displays them.
#import <Foundation/Foundation.h>
int main (int argc, char * argv[]) {
#autoreleasepool {
int number, remainder, total;
NSLog(#"Enter your number");
scanf("%i", &number);
while (number != 0)
{
remainder = number % 10;
total += remainder;
number /= 10;
}
NSLog(#"%i", total);
}
return 0;
}
My questions are:
Why is the program set to continue as long as the number is not equal to 0? Shouldn't it continue as the long as the remainder is not equal to 0?
At what point is the remainder discarded from the value of number? Why is there no number -= remainder statement before n /=10?
[Bonus question: Does Objective-C get any easier to understand?]
The reason we continue until number != 0 instead of using remainder is that if our input is divisible by 10 exactly, then we don't get the proper output (the sum of the base 10 digits).
The remainder is dropped off because of integer division. Remember, an integer cannot hold a decimal place, so when we divide 16 by 10, we don't get 1.6, we just get 1.
And yes, Objective-C does get easier over time (but, as a side-note, this uses absolutely 0 features of Objective-C, so it's basically C with a NSLog call).
Note that the output isn't quite what you would expect at all times, however, as in C / ObjC, a (unlike languages like D or JS) a variable is not always initialized to a set value (in this case, you assume 0). This could cause UB down the road.
It checks to see if number is not equal to zero because remainder very well may never become zero. If we were to input 5 as our input value, the first time through the loop remainder would be set to 5 (because 5 % 10 = 5), and number would go to zero because
5 / 10 = 0.5, and ints do not store floating point values, so the .5 will get truncated and the value of number will equal zero.
The remainder does not get removed from the value of number in this code. I think that you may be confused about what the modulo operator does (see this explanation).
Bonus answer: learning a programming language is difficult at first, but very rewarding in the long run (if you stick with it). Each new language that you learn after your first will most likely be easier to learn too, because you will understand general programming constructs and practices. The best of luck on your endeavor!