How to use approximately equal operator in objective-c? - objective-c

I am not sure how to do achieve this logic.
I have an array of numbers:
num = # [0,0.5,1,1.5,2...,12.5,13,13.5,14,14.5,15,15.5.....75];
These numbers are increased with a difference of .5
and I have a result number 'x'.
I want to find out which number in the array is the close match to the 'x' .
Which mathematical operator should I use ? much less << ? or approximately equal ~~ operator in objective-c ?
I can do if (x<<y) in xcode but I cannot do x ~~ y.
At the moment I'm using the following way suggested in here:
static bool CloseEnoughForMe(double value1, double value2, double acceptableDifference)
{
return fabs(value1 - value2) <= acceptableDifference;
}
Is there any simpler method that objective-c provides ?

There are no such operators in Objective-C (or C). You will have to do your own checking. Since each number in your array is 0.5 from the next value, you know the number you wish to check will be closest to a value in the array +/- 0.25.
Something like this perhaps:
double x = ... // The number to check
NSArray *numbers = #[ #0, #0.5, #1, #1.5, ..., 75 ]; // Your array of numbers
for (NSNumber *number in numbers) {
if (x >= [number doubleValue] - 0.25 || x < [number doubleValue] + 0.25) {
NSLog(#"%f is closest to %#", x, number);
break;
}
}
You'll need to add a little extra logic if x is less than -0.5 or greater than 75.5.

Related

How to print out an integer raised to the 100th power (handling overflow)

So my friend asked me this question as interview practice:
Using Objective-C & Foundation Kit, Write a method that takes a single digit int, and logs out to the console the precise result of that int being raised to the power of 100.
Initially I thought it sounded easy, but then I realized that even a single digit number raised to the power of 100 would quickly come close to 100 digits, which would overflow.
So I tried tackling this problem by creating an NSArray w/ NSNumbers (for reflection), where each object in the array is a place in the final result number. Then I perform the multiplication math (including factoring in carries), and then print out a string formed by concatenating the objects in the array. Here is my implementation w/ input 3:
NSNumber *firstNum = [NSNumber numberWithInteger:3];
NSMutableArray *numArray = [NSMutableArray arrayWithArray:#[firstNum]];
for( int i=0; i<99; i++)
{
int previousCarry = 0;
for( int j=0; j<[numArray count]; j++)
{
int newInt = [firstNum intValue] * [[numArray objectAtIndex:j] intValue] + previousCarry;
NSNumber *calculation = [NSNumber numberWithInteger:newInt];
previousCarry = [calculation intValue]/10;
NSNumber *newValue = [NSNumber numberWithInteger:(newInt % 10)];
[numArray replaceObjectAtIndex:j withObject:newValue];
}
if(previousCarry > 0)
{
[numArray addObject:[NSNumber numberWithInteger:previousCarry]];
}
}
NSArray* reversedArray = [[numArray reverseObjectEnumerator] allObjects];
NSString *finalNumber = [reversedArray componentsJoinedByString:#""];
NSLog(#"%#", finalNumber);
This isn't a problem out of a textbook or anything so I don't have any reference to double check my work. How does this solution sound to you guys? I'm a little worried that it's pretty naive even though the complexity is O(N), I can't help but feel like I'm not utilizing a type/class or method unique to Objective-C or Foundation Kit that would maybe produce a more optimal solution-- or at the very least make the algorithm cleaner and look more impressive
Write a method that takes a single digit int, and logs out to the console the precise result of that int being raised to the power of 100.
That strikes me as a typical interview "trick"[*] question - "single digit", "logs out to console"...
Here goes:
NSString *singleDigitTo100(int d)
{
static NSString *powers[] =
{
#"0",
#"1",
#"1267650600228229401496703205376",
#"515377520732011331036461129765621272702107522001",
#"1606938044258990275541962092341162602522202993782792835301376",
#"7888609052210118054117285652827862296732064351090230047702789306640625",
#"653318623500070906096690267158057820537143710472954871543071966369497141477376",
#"3234476509624757991344647769100216810857203198904625400933895331391691459636928060001",
#"2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376",
#"265613988875874769338781322035779626829233452653394495974574961739092490901302182994384699044001"
};
return powers[d % 10]; // simple bounds check...
}
And the rest is easy :-)
And if you are wondering, those numbers came from bc - standard command line calculator in U*ix and hence OS X. You could of course invoke bc from Objective-C if you really want to calculate the answers on the fly.
[*] It is not really a "trick" question but asking if you understand that sometimes the best solution is a simple lookup table.
As you have correctly figured out, you will need to use some sort of big integer library. This is a nice example you can refer to: https://mattmccutchen.net/bigint/
Furthermore, you can calculate x^n in O(lg(n)) rather than in O(n), using divide and conquer:
f(x, n):
if n == 0: # Stopping condition
return 1
temp = f(n/2)
result = temp * temp
if n%2 == 1:
result *= x
return result
x = 5 # Or another one digit number.
n = 100
result = f(x, 100) # This is the result you are looking for.
Note that x represents your integer and n the power you are raising x to.

Objective-C: Flooring to 3 decimals correctly

I am trying to floor a float value to the third decimal. For example, the value 2.56976 shall be 2.569 not 2.570. I searched and found answers like these:
floor double by decimal place
Such answers are not accurate. For example the code:
double value = (double)((unsigned int)(value * (double)placed)) / (double)placed
can return the value - 1 and this is not correct. The multiplication of value and placed value * (double)placed) could introduce something like: 2100.999999996. When changed to unsigned int, it becomes 2100 which is wrong (the correct value should be 2101). Other answers suffer from the same issue. In Java, you can use BigDecimal which saves all that hassels.
(Note: of course, rounding the 2100.9999 is not an option as it ruins the whole idea of flooring to "3 decimals correctly")
The following code should work:
#include <stdio.h>
#include <math.h>
int main(void) {
double value = 1.23456;
double val3;
val3 = floor(1000.0 * value + 0.0001) * 0.001; // add 0.0001 to "fix" binary representation problem
printf("val3 is %.8f; the error is %f\n", val3, 1.234 - val3);
}
this prints out
val3 is 1.23400000; the error is 0.000000
If there are any residual errors, it comes about from the fact that floating point numbers cannot necessarily be represented exactly - the idea behind BigDecimal and things like that is to work around that in a very explicit way (for example by representing a number as its digits, rather than a binary representation - it's less efficient, but maintains accuracy)
I had to consider a solution involving NSString and it worked like a charm. Here is the full method:
- (float) getFlooredPrice:(float) passedPrice {
NSString *floatPassedPriceString = [NSString stringWithFormat:#"%f", passedPrice];
NSArray *floatArray = [floatPassedPriceString componentsSeparatedByString:#"."];
NSString *fixedPart = [floatArray objectAtIndex:0];
NSString *decimalPart = #"";
if ([floatArray count] > 1) {
NSString *decimalPartWhole = [floatArray objectAtIndex:1];
if (decimalPartWhole.length > 3) {
decimalPart = [decimalPartWhole substringToIndex:3];
} else {
decimalPart = decimalPartWhole;
}
}
NSString *wholeNumber = [NSString stringWithFormat:#"%#.%#", fixedPart, decimalPart];
return [wholeNumber floatValue];
}
For example, the value 2.56976 shall be 2.569 not 2.570
Solution is has simple as that :
double result = floor(2.56976 * 1000.0) / 1000.0;
I don't know why you search complication... this works perfectly, doesn't need to pass by some unsigned int or other + 0.0001 or whatever.
Important note :
NSLog(#"%.4f", myDouble);
Actually do a round on your variable. So it's improper to believe you can floor with a %.Xf

Generating Combinatorics of Large Numbers in Obj-C

tl;dr: How should I be dealing with numbers like 20! * 20! in Objective-C?
I'm learning Objective-C by working through Project Euler. It's been quite fun, but one problem I've been running in to is working with arbitrarily large numbers. I'm still pretty green on these things, so I don't know why something like, say, Python, handles large numbers with ease compared to Obj-C.
Take for example Problem 15:
Starting in the top left corner of a 2 x 2 grid, there are 6 routes (without backtracking) to the bottom right corner.
How many routes are there through a 20 x 20 grid?
That's easy. Using combinatorics:
(20+20)! / 20!(20!)
-> 815915283247897734345611269596115894272000000000 / 5919012181389927685417441689600000000
-> 137846528820
In Python:
import math
print math.factorial(40) / (math.factorial(20) * math.factorial(20))
In Objective-C, though? I have't yet found a way to force such a large numbers through. Using the 2 x 2 example works fine. I can get 9C4 = 126, as it should be. But how should I be dealing with numbers like 20!?
I've dallied with trying to use NSDecimalNumber, which appears to support more numerals per number, assuming you can convert it to Mantissa x Exponent and don't mind loss of precision, but that didn't prove to be too useful, as I couldn't figure out how to have Obj-C create a Mantissa from a %llu and I do mind loss of precision.
The code I have so far properly generates the factorials, as it appears unsigned long long handles values so large, but chokes up on x * y, and thus getCombinatoricOf:20 and:20 returns 1.
#import "Problem15.h"
#implementation Problem15
- (unsigned long long)factorial:(NSNumber *)number {
unsigned long long temp = 1;
for (int i = [number intValue]; i > 0; i--) {
temp *= i;
}
return temp;
}
- (unsigned long long)getCombinatorcOf:(NSNumber *)x and:(NSNumber *)y {
NSNumber *n = #([x intValue] + [y intValue]);
NSNumber *n_factorial = #([self factorial:n]);
NSNumber *x_factorial = #([self factorial:x]);
NSNumber *y_factorial = #([self factorial:y]);
return ([n_factorial unsignedLongLongValue] / ([x_factorial unsignedLongLongValue] * [y_factorial unsignedLongLongValue]));
}
- (NSString *)answer {
NSNumber *x = #5;
NSNumber *y = #4;
unsigned long long answer = [self getCombinatoricOf:x and:y];
return [NSString stringWithFormat:#"\n\nProblem 15: \nHow many routes are there through a 20 x 20 grid? \n%llu", answer];
}
#end
It's not Objective-C, but you could just use GMP just as an ordinary C library.
There are also Objective-C wrappers fo GMP, like GMPInt.

How to handle floats and doubles when implementing -hash in objective-c

I'm a newbie at Objective-C and I'm looking for the best way to handle primitive floats and double when implementing the -hash method in an Objective-C class. I've found some good advise on isEqual and hash in general in this question:
Best practices for overriding isEqual: and hash
but it doesn't say anything on how to deal with floats and doubles.
My best attempt:
...
long lat = [[NSNumber numberWithDouble:self.latitude] longValue];
result = prime * result + (int) (lat ^ (lat >>> 32));
...
but I'm not sure this is the correct way. Any ideas ?
On the assumption that Apple's implementation of -hash is adequate, what is wrong with
result = [[NSNumber numberWithDouble: [self latitude]] hash];
Or using the modern syntax
result = [#([self latitude]) hash];
Advice of #JeremyP about using NSNumber was pretty good, but I followed this more into depth. Since CoreFoundation is open source, I found how does CFNumber implement hashing function and this is what I found:
Split the number to integral and fraction part, hash both parts and sum them. Integral part is hashed by modulo and a hash-factor, fraction part is hashed only by multiplication.
NSUInteger HashDouble(double value) {
double absolute = ABS(value);
double integral = round(absolute);
double fragment = absolute - integral;
NSUInteger integralHash = 2654435761U * fmod(integral, NSUIntegerMax);
NSUInteger fragmentHash = fragment * NSUIntegerMax;
return integralHash + fragmentHash;
}
Original source code from CoreFoundation wth comments:
/* For use by NSNumber and CFNumber.
Hashing algorithm for CFNumber:
M = Max CFHashCode (assumed to be unsigned)
For positive integral values: (N * HASHFACTOR) mod M
For negative integral values: ((-N) * HASHFACTOR) mod M
For floating point numbers that are not integral: hash(integral part) + hash(float part * M)
HASHFACTOR is 2654435761, from Knuth's multiplicative method
*/
#define HASHFACTOR 2654435761U
CF_INLINE CFHashCode _CFHashInt(long i) {
return ((i > 0) ? (CFHashCode)(i) : (CFHashCode)(-i)) * HASHFACTOR;
}
CF_INLINE CFHashCode _CFHashDouble(double d) {
double dInt;
if (d < 0) d = -d;
dInt = floor(d+0.5);
CFHashCode integralHash = HASHFACTOR * (CFHashCode)fmod(dInt, (double)ULONG_MAX);
return (CFHashCode)(integralHash + (CFHashCode)((d - dInt) * ULONG_MAX));
}
From file ForFoundationOnly.h on opensource.apple.com.

How do you get the int and modulo (mod) of division with an NSDecimalNumber

I am confused by NSDecimalNumber and its "behaviors". I have an NSDecimalNumber that represents a dollar value, say $37.50. I'd like to find out how many times say 5.0 goes into that number and then know what's left over. I can get the straight division and get 7.50 but I want 7 mod 2.50. I could convert to an integer but need to save the "cents" so wondering if there's some tricks in the framework?
Using Peter Hoseys example, but with iOS code:
NSDecimalNumber *dividend = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:37.5] decimalValue]];
NSDecimalNumber *divisor = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:5.0] decimalValue]];
NSDecimalNumber *quotient = [dividend decimalNumberByDividingBy:divisor withBehavior:[NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]];
NSDecimalNumber *subtractAmount = [quotient decimalNumberByMultiplyingBy:divisor];
NSDecimalNumber *remainder = [dividend decimalNumberBySubtracting:subtractAmount];
Divide the dividend by the divisor, rounding down. This gets you the quotient.
Multiply the divisor by the quotient.
Subtract that from the dividend. This gets you the remainder.
(37.50 // 5) == 7; 7 * 5 == 35; 37.50 - 35 = 2.50.
(Note: // is Python's operator for integral division. I've borrowed it here. Obviously, you should not actually attempt to use // for division in Objective-C code.)
Here's a NSDecimalNumber category which also works with negative numbers and negative divisors:
- (BOOL)isNegative
{
return (NSOrderedDescending == [[NSDecimalNumber zero] compare:self]);
}
- (NSDecimalNumber *)invertedNumber
{
NSDecimalNumber *negOne = [NSDecimalNumber decimalNumberWithMantissa:1 exponent:0 isNegative:YES];
return [self decimalNumberByMultiplyingBy:negOne];
}
- (NSDecimalNumber *)moduloFor:(NSDecimalNumber *)divisor
{
NSRoundingMode roundingMode = ([self isNegative] ^ [divisor isNegative]) ? NSRoundUp : NSRoundDown;
NSDecimalNumberHandler *rounding = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundingMode
scale:0
raiseOnExactness:NO
raiseOnOverflow:NO
raiseOnUnderflow:NO
raiseOnDivideByZero:NO];
// divide and get the remainder
NSDecimalNumber *quotient = [self decimalNumberByDividingBy:divisor withBehavior:rounding];
NSDecimalNumber *subtract = [quotient decimalNumberByMultiplyingBy:divisor];
NSDecimalNumber *modulo = [self decimalNumberBySubtracting:subtract];
if ([divisor isNegative]) {
return [modulo invertedNumber];
}
return modulo;
}
Same solution in Swift 4:
let dividend = NSDecimalNumber(string: Price)
let divisor = NSDecimalNumber(decimal: 0.05)
let quotient = dividend.dividing(by: divisor, withBehavior: NSDecimalNumberHandler(roundingMode: .down, scale: 0, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: false))
let subtractAmount = quotient?.multiplying(by: divisor)
let remainder = dividend.subtracting(anAmount)
if remainder != 0
{ ...
You could theoretically do some tricks with the NSDecimalNumber methods decimalNumberByDividingBy:, decimalNumberByMultiplyingBy:, and decimalValue. Divide the numbers, grab the decimal number structure, figure out the remainder from the structure, then create a new decimal number with that remainder and multiply that remainder by the original number.
The easier way to do it, however, would probably be to figure out the maximum precision you want (call it N places after the decimal point), multiply the number by 10eN, then just grab the integer value and do your division and mod on that. You run the risk of losing data, especially with very large numbers, however, so check the biggest number you want and figure out what data type - if any - will work for you. NSNumber does support unsignedLongLongValue.