Floating Point things work.....Most of the time [duplicate] - objective-c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Correcting floating point numbers
float randNum = arc4random()%(100)-1;
I read somewhere that this will give me random numbers between 1-100. Or something close to that.
This line seems to work all the time, but I convert this number to an NSString for storage/printing to text, and then convert it back to a float for ordering and other calculations. But when I get that float back sometimes it looks something like gibberish; like this in the variable view:
9 float 9.75303731e-41
Why would converting to an NSString and back to a float ruin the float value I'm using? (e.g. What could I have screwed up? Or should I be using CGFloat instead?)
I think this is all the pertinent code:
NSMutableArray *stringArray = [[NSMutableArray alloc] init];
floatArray[30];
// put three random floats into an NSMutableArray of NSStrings
for(int i = 0; i < 3; i++)
{
float randNum = arc4random()%(100)-1;
NSString *randString = [NSString stringWithFormat:#"%.3f", randNum];
[stringArray addObject:randString];
}
// convert NSStrings back to float
for(NSString *string in stringArray)
{
float temp = [string floatValue];
floatArray[iterator] = temp;
}
Thanks in advance for any help/advice.
EDIT: When I step through the code it looks like the float value looks sane until the line "float temp = [string floatValue]", which is where the value seems to be garbaged.

Why are you using float when the result from arc4random() is a uint32_t? Switching to integer types would almost certainly get around all this, as I suspect the problem is because of the conversion to string form allowing only 3 significant digits. What happens if you use %.15f as your format?
Sidenote: use arc4random_uniform() - it's simpler and guaranteed to be a uniformly random distribution within that range.

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.

Count number of arbitrary repeating decimal numbers in NSString

In my code, I'm dealing with an NSString that contains an NSNumber value. This NSNumber value could possibly be a repeating decimal number (e.x. 2.333333333e+06) that shortens to "2.333333" in a string format. It could also be a terminating number (e.x. 2.5), negative, or irrational number (2.398571892858...) (only dealing with decimals here)
I need to have a way to figure out if there are the repeating numbers in the string (or the NSNumber, if necessary). In my code, I would have no way to know what the repeating number would be, as it's a result of computations started by the user. I have tried this for loop (see below) that doesn't work the way I want it to, due to my inexperience with string indexing/ranges/lengths.
BOOL repeat = NO; //bool to check if repeating #
double repNum, tempNum; //run in for loop
NSString *repeating = [numVal stringValue]; //string that holds possible repeating #
for (int i = 3; i <= [repeating length]-3; i++) { //not sure about index/length here
if (i == 3) {
repNum = [repeating characterAtIndex:i];
}
tempNum = [repeating characterAtIndex:i];
if (tempNum == repNum) {
repeat = YES;
} else {
repeat = NO;
}
}
This code doesn't work as I'd like it to, mainly because I also have to account for negative dashes in the string and different amounts of numbers (13 1/3 vs. 1 1/3). I've used the modffunction to separate the integers from the decimals, but that hasn't worked well for me either.
Thank you in advance. Please let me know if I can clarify anything.
EDIT:
This code works with the finding of different solutions for polynomials (quadratic formula). Hope this helps put it into context. See here. (Example input)
NSNumber *firstPlusSolution, *secondMinusSolution;
NSString *pValueStr, *mValueStr;
firstPlusSolution = -(b) + sqrt(square(b) - (4)*(a)*(c)); //a, b, c: "user" provided
firstPlusSolution /= 2*(a);
secondMinusSolution = -(b) - sqrt(square(b) - 4*(a)*(c));
secondMinusSolution /= 2*(a);
pValueStr = [firstPlusSolution stringValue];
mValueStr = [secondMinusSolution stringValue];
if ([NSString doesString:pValueStr containCharacter:'.']) { //category method I implemented
double fractionPart, integerPart;
fractionPart = modf(firstPlusSolution, &integerPart);
NSString *repeating = [NSString stringWithFormat:#"%g", fractionPart];
int repNum, tempNum;
BOOL repeat = NO;
//do for loop and check for negatives, integers, etc.
}
if ([NSString doesString:mValueStr containCharacter'.']) {
//do above code
//do for loop and check again
}
Use C. Take the fractional part. Convert to a string with a known accuracy. If length of string indicates that last digits are missing, then it does not repeat. Use NSString-UTF8String to convert a string. Get rid of the last digit (may be rounding or actual floating point arithmetic error). Use function int strncmp ( const char * str1, const char * str2, size_t num ) to perform comparison within the string itself. If the result is 8 characters long and the last 2 characters match the first 2 characters, then shall the first 6 characters be considered repeating?
Assuming that fraction knowledge your desire:
• Possibility 1: Use fractions. Input fractions. Compute with fractions. Output fractions. Expand upon one of the many examples of a c++ fraction class if necessary and use it.
• Possibility 2: Choose an accuracy which is much less than double. Make a fraction from the result. Reduce the fraction allowing rounding based upon accuracy.
I suggest use not optimal but easy to write solution
Create NSMutableDictionary that will contain number as key and count of occurrence as value.
You can use componentsSeparatedByString: if numbers in string delimited by known symbol
In loop check valueForKey in dictionary and if need increase value
Last step is analyzing our dictionary and do anything you need with numbers

NSNumber decimal to C primitive value?

I want to convert a decimal NSNumber to an int or other form which I can do math with. Here's the annotated code for my project:
NSNumber *Left = [left valueForOutputKey:#"Y"];
This line gets a Quartz Composer Outlet, usually with a value around 0.512.
Basically, I want to multiply this by 10, and then do some operations like greater than and less than to see which range it is in.
Since it looks like you're dealing with a fractional component, you want to convert it to a float or a double to perform your operations, depending on how big you expect that value to be. A float should be fine unless you're dealing with ridiculously large or precise numbers. Here's how it would look, for example:
float lValue = [[left valueForOutputKey:#"Y"] floatValue];
lValue *= 10;
if (lValue < 10) {
// do whatever
}
else if (lValue > 50) {
// do whatever
}
Then to store the value back in your outlet or whatever, you pack it back into a NSNumber:
NSNumber *newValue = [NSNumber numberWithFloat:lValue];
[left setValue:newValue forKey:#"Y"];
You may have to convert newValue into a string to display it in a control, just use [newValue stringValue] to do that.
Use one of the methods of NSNumber:
int leftInt = [Left intValue];
float leftFloat = [Left floatValue];
double leftDouble = [Left doubleValue];

Problem while converting NSData to int

Using foundation and cocoa frameworks on Mac, I am trying to convert an NSData object in humanly understandable number.
Let say the NSData object is an image of NPIXEL. I know the binary data are coded in big endian and represent 32 bit integer (to be more precise 32 bit two complements integer). I write the piece of code bellow to convert the NSData into an int array. But the value I got are completely wrong (this does not means the measurement are bad, I used a special software to read the data and the value given by the software are different from the one I got with my code).
-(int *) GetArrayOfLongInt
{
//Get the total number of element into the Array
int Nelements=[self NPIXEL];
//CREATE THE ARRAY
int array[Nelements];
//FILL THE ARRAY
int32_t intValue;
int32_t swappedValue;
double Value;
int Nbit = abs(BITPIX)*GCOUNT*(PCOUNT + Nelements); Nbit/=sizeof(int32_t);
int i=0;
int step=sizeof(int32_t);
for(int bit=0; bit < Nbit; bit+=step)
{
[Img getBytes:&swappedValue range:NSMakeRange(bit,step)];
intValue= NSSwapBigIntToHost(swappedValue);
array[i]=intValue;
i++;
}
return array;
}
This piece of code (with minor change) work perfectly when the binary data represent float or double, but I dont when it is 16,32 or 64 bit integer. I also tried changingNSSapBigIntToHostintoNSSwapLittleInttoHost`. I even tried with long, but the results is still the same, I got bad values. What wrong I am doing ?
PS: Some of the variable in my code are already set elsewhere in my program. BITPIX is the bit size of each pixel. In this case 32. GCOUNT is equal to 1, PCOUNT 0 and Nelements is the total number of pixel I should have in my image.
Returning a pointer to a local variable is a very bad idea. array could get overwritten at any time (or if you were to write through the pointer, you could corrupt the stack). You probably want something like:
// CREATE THE ARRAY
int *array = malloc(Nelements * sizeof(int));
Your algorithm seems a bit overkill, too. Why not just copy out the whole array from the NSData object, and then byteswap the entries in place? Something like:
int32_t length = [Img length];
int32_t *array = malloc(length);
[Img getBytes:array length:length];
for (i = 0; i < length/sizeof(int32_t); i++)
{
array[i] = NSSwapBigIntToHost(array[i]);
}

How to convert a string into double and vice versa?

I want to convert a string into a double and after doing some math on it, convert it back to a string.
How do I do this in Objective-C?
Is there a way to round a double to the nearest integer too?
You can convert an NSString into a double with
double myDouble = [myString doubleValue];
Rounding to the nearest int can then be done as
int myInt = (int)(myDouble + (myDouble>0 ? 0.5 : -0.5))
I'm honestly not sure if there's a more streamlined way to convert back into a string than
NSString* myNewString = [NSString stringWithFormat:#"%d", myInt];
To really convert from a string to a number properly, you need to use an instance of NSNumberFormatter configured for the locale from which you're reading the string.
Different locales will format numbers differently. For example, in some parts of the world, COMMA is used as a decimal separator while in others it is PERIOD — and the thousands separator (when used) is reversed. Except when it's a space. Or not present at all.
It really depends on the provenance of the input. The safest thing to do is configure an NSNumberFormatter for the way your input is formatted and use -[NSFormatter numberFromString:] to get an NSNumber from it. If you want to handle conversion errors, you can use -[NSFormatter getObjectValue:forString:range:error:] instead.
Adding to olliej's answer, you can convert from an int back to a string with NSNumber's stringValue:
[[NSNumber numberWithInt:myInt] stringValue]
stringValue on an NSNumber invokes descriptionWithLocale:nil, giving you a localized string representation of value. I'm not sure if [NSString stringWithFormat:#"%d",myInt] will give you a properly localized reprsentation of myInt.
Here's a working sample of NSNumberFormatter reading localized number String (xCode 3.2.4, osX 10.6), to save others the hours I've just spent messing around. Beware: while it can handle trailing blanks such as "8,765.4 ", this cannot handle leading white space and this cannot handle stray text characters. (Bad input strings: " 8" and "8q" and "8 q".)
NSString *tempStr = #"8,765.4";
// localization allows other thousands separators, also.
NSNumberFormatter * myNumFormatter = [[NSNumberFormatter alloc] init];
[myNumFormatter setLocale:[NSLocale currentLocale]]; // happen by default?
[myNumFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
// next line is very important!
[myNumFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; // crucial
NSNumber *tempNum = [myNumFormatter numberFromString:tempStr];
NSLog(#"string '%#' gives NSNumber '%#' with intValue '%i'",
tempStr, tempNum, [tempNum intValue]);
[myNumFormatter release]; // good citizen
olliej's rounding method is wrong for negative numbers
2.4 rounded is 2 (olliej's method gets this right)
−2.4 rounded is −2 (olliej's method returns -1)
Here's an alternative
int myInt = (int)(myDouble + (myDouble>0 ? 0.5 : -0.5))
You could of course use a rounding function from math.h
// Converting String in to Double
double doubleValue = [yourString doubleValue];
// Converting Double in to String
NSString *yourString = [NSString stringWithFormat:#"%.20f", doubleValue];
// .20f takes the value up to 20 position after decimal
// Converting double to int
int intValue = (int) doubleValue;
or
int intValue = [yourString intValue];
For conversion from a number to a string, how about using the new literals syntax (XCode >= 4.4), its a little more compact.
int myInt = (int)round( [#"1.6" floatValue] );
NSString* myString = [#(myInt) description];
(Boxes it up as a NSNumber and converts to a string using the NSObjects' description method)
For rounding, you should probably use the C functions defined in math.h.
int roundedX = round(x);
Hold down Option and double click on round in Xcode and it will show you the man page with various functions for rounding different types.
This is the easiest way I know of:
float myFloat = 5.3;
NSInteger myInt = (NSInteger)myFloat;
from this example here, you can see the the conversions both ways:
NSString *str=#"5678901234567890";
long long verylong;
NSRange range;
range.length = 15;
range.location = 0;
[[NSScanner scannerWithString:[str substringWithRange:range]] scanLongLong:&verylong];
NSLog(#"long long value %lld",verylong);
convert text entered in textfield to integer
double mydouble=[_myTextfield.text doubleValue];
rounding to the nearest double
mydouble=(round(mydouble));
rounding to the nearest int(considering only positive values)
int myint=(int)(mydouble);
converting from double to string
myLabel.text=[NSString stringWithFormat:#"%f",mydouble];
or
NSString *mystring=[NSString stringWithFormat:#"%f",mydouble];
converting from int to string
myLabel.text=[NSString stringWithFormat:#"%d",myint];
or
NSString *mystring=[NSString stringWithFormat:#"%f",mydouble];
I ended up using this handy macro:
#define STRING(value) [#(value) stringValue]