How to Multiply Two textfield values Without converting the text into integer or Number - iphone

I have two text fields and user entered the values. I can get the values of textFields like below
NSString *number1 = firstTextField.text;
NSString *number2 = secondTextField.text;
I want to multiply number1 and number2 without converting them into integer or number.I am doing like below
NSExpression *expression = [NSExpression expressionWithFormat:[NSString stringWithFormat:#"%#*%#",number1,number2]];NSLog(#"Multiplication result is----%#",[expression expressionValueWithObject:nil context:nil]);
I don't know if it is correct or not. If it is not correct please give me the suggestions how it can be possible.

By using NSExpression is one way to Multiply/Add/Subtract two number strings without converting them into integer or number.
NSExpression *expression = [NSExpression expressionWithFormat:expressionFormat];
You are using here expressionFormat as [NSString stringWithFormat:#"%#*%#",number1,number2];.
If you want to add or subtract number1 and number2 then replace * with + or -. In this way you have to proceed.

If the question was in an interview.
The interviewers were probably expecting you to write a method to go through both arrays and multiply the characters (converting one by one to integers) or (also identifying the represented character to know the equivalent integer number).
Searching on google there are some examples in different languages.
JAVA
http://csjobinterview.wordpress.com/2012/04/05/string-multiplication/
string multiplication
C++
Multiplying two number arrays
It is a common question in interviews.

I simply used textfields... and used the values that the user input into those textfields... here is one calculation example that has worked for me... in this example the user is trying to find the volume of beachstone they would need to order... the formula is pretty straight forward. Make sure you use the math brackets () to distinguish order of operations...
-(IBAction)calculate_beachstone:(id)sender {
float floatanswer =
([area1.text floatValue])+([area2.text floatValue])+([area3.text floatValue])+([area4.text floatValue])+([area5.text floatValue])+([area6.text floatValue])+([area7.text floatValue])+([area8.text floatValue])+([area9.text floatValue])+([area10.text floatValue]))
*([beachstone_depth.text floatValue])/12)/27);
NSString *stringRectResult=[[NSString alloc]
initWithFormat:#"%.1f",floatanswer];
answer_beachstone.text=stringRectResult;
}
I am adding the text found in the textfield (which user can only use numbers for input - custom keyboard)... in this example I have up to 10 fields which can be added together... then I use the * (multiply) to apply a depth in this example, and convert it back to a text string so I can display the result somewhere else...
In fact, if you write this part answer_beachstone to NSUserDefaults, you can use the result anywhere in different controllers, by calling it back.
If you're interested, here is how I did that...
-(IBAction)save_answer_beachstone:(id)sender {
save_answer_beachstone = [[NSString alloc] initWithString:answer_beachstone.text];
[answer_beachstone setText:save_answer_beachstone];
NSUserDefaults *save = [NSUserDefaults standardUserDefaults];
[save setObject:save_answer_beachstone forKey:#"save_answer_beachstone"];
}
Then I can use the resulting "answer" in any controller inside viewDidLoad...
[answer_beachstone setText:[[NSUserDefaults standardUserDefaults] objectForKey:#"save_answer_beachstone"]];
I know the question was asked 4 years ago, but this formula syntax works for me in a number of ways, in various apps...

You can't multiply two strings. It's not possible.
For this you have to convert it into Integer or int using NSNumber or using:
[secondTextField.text intValue].
NSInteger number = [firstTextField.text integerValue]*[secondTextField.text integerValue];

Related

NSExpression Dividing Lower Number By Higher Number [duplicate]

I am making a calculator that logs input in a label named "inputLabel' and then outputs the answer in a different label named "outputLabel" (similar to a graphing calculator). Once the user is finished entering the expression, the expression is stored in an NSString object and then parsed with the NSPredicate class and evaluated with the NSExpression class. What I have works, but I have noticed for particular operations the answers are not correct. For example, if the user types in "25/2" the calculator returns 12, which is obviously incorrect. However, if the user types in "25/2.0" or "25.0/2" the calculator returns 12.5 which is what I want. It seems that the NSExpression method 'expressionValueWithObject' is interpreting the operands as integers instead of floats. If this is the case, is there a way that I change the 'expressionValueWithObject'method to interpret the operands as floats?
Brain.m
-(float)performCalculation: (NSString *)operation
{
NSPredicate *parsed = [NSPredicate predicateWithFormat:[operation stringByAppendingString:#"=1.0"]];
NSExpression *inputExpressionParsed = [(NSComparisonPredicate *)parsed leftExpression];
NSNumber *result = [inputExpressionParsed expressionValueWithObject:inputExpressionParsed context:nil];
return [result floatValue];
}
ViewController.m
- (IBAction)equalsPressed:(id)sender
{
//self.inputLabel.text = [self.inputLabel.text stringByAppendingString:#".0"];
NSString *inputExpression = self.inputLabel.text;
self.inputLabel.text = [self.inputLabel.text stringByAppendingString:#"="];
float result = [self.brain performCalculation:inputExpression];
self.outputLabel.text = [NSString stringWithFormat:#"%g", result];
}
No, NSExpression cannot do that. You could try to append ".0" to all integer numbers
in the string before evaluating it, but the better solution is probably to use a "proper"
math expression parser, for example
https://github.com/davedelong/DDMathParser
You could iterate through the expression tree replacing the expression with the integer value (expressionType == NSConstantExpression). It depends a little bit of the features of your calculator, whether it is worth or not.

formatting NSDecimalNumber issue

I'm trying to create NSDecimalNumber with simply format like: 123.00 with two fractional digits after dot, always. I tried use the NSFormatter and many other ways like converting float from string and creating then NSDecimalNumber from this string, but it's not working.
The problem is that I need only NSDecimalNumber in this format, not NSString or any other.
Thanks for any advice,
Paul
You may get idea from this.
float num = 123.1254546;
NSString *str = [NSString stringWithFormat:#"%.2f",num];
NSLog(#"%.2f %#",num,str);
I think you simply need to do Type Casting operation for Two times as bellow
float value = 123.562;
int myDigit = value;
it gives value 123 in myDigit variable
NSLog(#"MyDigit in Decimal = %d",myDigit);
Output is MyDigit in Decimal = 123
now if you want output like 123.000 then simply write as bellow
float valueWithZiro = myDigit;
NSLog(#"MyDigit with 000 == %3f",valueWithZiro);
Output is MyDigit in Decimal = 123.000
NSDecimalNumber, like NSNumber, cannot contain formatting information. The object structure simply doesn't support it. It represents a number, not the way the number is displayed.
You can convert it to a formatted NSString (which you say you don't want). But you can't do what you're asking.
You convert it to a formatted NSString using an NSNumberFormatter. It's the object that allows you to specify the decimal and thousands separators, number of decimal places to display, the currency symbol, etc.
Maybe you were looking to store a NSNumberDecimal with just two digits after the fraction?
If so NSDecimalNumberBehaviors is your friend.
I had a similar need and used the following:
self.decimalHandlingBehaviorForApp = [NSDecimalNumberHandler
decimalNumberHandlerWithRoundingMode:NSRoundUp
scale:2 raiseOnExactness:NO
raiseOnOverflow:NO raiseOnUnderflow:NO
raiseOnDivideByZero:YES];
Edit: added example of using it
// update the taxable total first
self.cartTaxableTotal = [self.cartTaxableTotal decimalNumberByAdding:itemAdded.priceOfItem
withBehavior:self.decimalHandlingBehaviorForApp];

What is the fastest routine to convert NSArrays to C-style (double) arrays?

I have 2 NSArray (Mutable, actually) that I am trying to convert to a C-style double array for a c routine i am passing them to.
Here is my Objective-C routine:
NSMutableDictionary *childDictionary = [myParentDictionary objectForKey:resort_code];
latitudeArray = [childDictionary objectForKey:#"lat"];
longitudeArray = [childDictionary objectForKey:#"lon"];
int nvert = [latitudeArray count];
double laArray[nvert];
double loArray[nvert];
for(int i=0; i<nvert; i++) {
double dLat = [[latitudeArray objectAtIndex:i]doubleValue];
double dLon = [[longitudeArray objectAtIndex:i]doubleValue];
laArray[i] = dLat;
loArray[i] = dLon;
}
This takes upwards of 3-8 seconds on the 3G iPhone (instantaneous on the simulator -- yet another reason to test on the device )
is there faster way? I have to end up with laArray[i] and loArray[i] as c-style arrays of doubles.
(to expand on the question for the benefit of a commenter):
Each array consists of #"38.448745" (lat) and #"-122.9847684" (lon) style content. I do this cos to be pushed onto an NSArray, the lat and lon need to be objects. I simply used:
[latitudeArray addObject:[NSString stringWithFormat: #"%.10f",dlat]];
[longitudeArray addObject:[NSString stringWithFormat: #"%.10f",dlon]];
I suppose I could change that to:
[latitudeArray addObject:[NSNumber numberWithDouble: #"%.10f",dlat]];
[longitudeArray addObject:[NSNumber numberWithDouble: #"%.10f",dlon]];
...which may reduce the conversion time of
double dLat = [[latitudeArray objectAtIndex:i]doubleValue];
but wouldn't I still need that exact line to convert from NSString to double? It just may work faster?
thx
dlat is a double, right?
So instead of:
[latitudeArray addObject:[NSString stringWithFormat: #"%.10f",dlat]];
Do:
[latitudeArray addObject:[NSNumber numberWithDouble:dlat]];
They both respond to doubleValue but the NSNumber should not have to do any string parsing since it's stored as a numeric value already. And you never have to go to a string at all.
I suspect you have an array of strings like #"213.12385" that need to be parsed and converted when you call doubleValue on them. If that is where the issue is, the C arrays have nothing to with this.
Only thing I would add here is to throw Shark on this and see where it's spending it's time. If it's spending time in doubleValue find a different way to parse the strings with preprocessing in background or something. If it's in objectAtIndex: perhaps fast enumeration would help. If it's somewhere else entirely then you know it's not this snippet that's slow.
For the general case of converting an NSArray to a C array, you can use getObjects:. In this case, though, want you actually want is not to convert the NSArray, but to derive an array of doubles from an NSArray of some unspecified object type.
One obvious way to speed things up would be fast enumeration rather than sending a message to get the object for each iteration of the loop. I suspect the real solution, though, is outside your algorithm. The slowness probably comes from transforming whatever objects the array contains into doubles, in which case you'll need to find a way around that — maybe store doubles all along, maybe do the conversion in the background, etc. If you're creating the arrays yourself and there isn't some compelling reason for the objects to be strings, you should use NSNumbers instead. Those should be quite a bit faster.
The best solution is probably to make sure those values never end up in an NSArray as NSString values. I would attack this at the source.
So you edited your question and added that you are actually building those arrays. So why not use native arrays of doubles or floats from the start? I usually recommend against this but in your case it sounds like there is a huge performance gain.
Possibly using fast iteration, but I doubt that will really speed up your loop.

Code to generate random strings creates same succession of identical strings

I have the following method that should create a 20 character ID (sometimes with a prefix) and return the ID.
It seems to reset on launch and every time I use it it will create the same succession of identical numbers.
+(NSString *)createUniqueIdentifier:(NSString *)withPrefix {
NSString *outstring = nil;
if (withPrefix!=nil && ![withPrefix isEqualToString:#""]) {
outstring = [withPrefix stringByAppendingString:#"-"];
} else {
outstring = #"";
}
NSInteger ii;
NSString *allletters = #"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (ii=0; ii<20; ii++) {
outstring = [outstring stringByAppendingString:[allletters substringWithRange:[allletters rangeOfComposedCharacterSequenceAtIndex:random()%[allletters length]]]];
}
return outstring;
}
I'm assuming this has something to do with random(), but I don't know what else to use. I think I even got that suggestion from Stack Overflow.
Thanks for any help!
When using random() you should set the seed value at program start, ie srandom(time(NULL));
My guess is that you probably need to set the seed since it'll use a default one if you don't.
You should at least use something based on the date/time to get something that varies for each run.
If you'd like a completely unique string, I'd use NSProcessInfo to generate one for you by calling:
[[NSProcessInfo processInfo] globallyUniqueString];
Unless you only want it to contain those letters mentioned.
I think I've figured it out. I changed random() to arc4random() and it magically seems to work now.
Here's the documentation on arc4random that probably has something to do with it:
The arc4random() function uses the key stream generator employed by the arc4 cipher, which uses 8*8 8 bit S-Boxes. The S-Boxes can be in about (21700) states. The arc4random() function returns pseudo-random numbers in the range of 0 to (232)-1, and therefore has twice the range of rand(3) and random(3) .
The arc4random_stir() function reads data from /dev/urandom and uses it to permute the S-Boxes via arc4random_addrandom().
There is no need to call arc4random_stir() before using arc4random(), since arc4random() automatically initializes itself.
FYI: If you absolutely need unique strings, create a UUID instead of using random, which has a minute chance of getting identical values.

Objective C - Adding characters at specific parts of a string

I have made a quadratic equation solver for the iPhone and when the text box is clicked, my own custom keypad appears. I have a button that changes whether the number is positive or negative. Right now I what happens is that when the button is pressed (0 - current value of text) is what is displayed in the text box, so if the number is positive, it will become negative and if it is negative it will become positive. I am having some problems doing this so what I wanted to is to put a minus sign at the beginning of the string if the number is positive and if the number is negative, the minus sign will be removed. Can anyone give me guidance on this?
Instead of negating using a mathematical function I assigned a NSMutableString to my UITextField then I inserted a "-" sign using insertString:atIndex: then I reassigned the changed string to my UITextField. To toggle between positive and negative, I created an if function so if the float value of my textfield is greater or equal to 0, then an "-" is inserted but if the float value of my text field is less than zero, the "-" is removed using deleteCharactersInRange. Here is my code as it stands:
- (IBAction)positivity{
NSMutableString *a = [NSMutableString stringWithString:aVal.text];
if([aVal.text floatValue]>=0){
[a insertString: #"-" atIndex: 0];
aVal.text = a;
}
else if([aVal.text floatValue]<0){
NSRange range = {0,1};
[a deleteCharactersInRange:range];
aVal.text = a;
}
}
aVal is the name of the UITextField that i am changing.
An alternative to the straight string approach is to not use a string. A while back I wrote a graphing calculator for iPhone that stored the equation internally in an NSMutableArray of NSStrings. Each slot in the array corresponded to one element in the equation, such as "x", "^", "sin(", etc.
When I needed to negate the equation, it was much easier to tell the array to insertObject:#"-" atIndex:0 than to try and insert it directly into the string. Then whenever the array was changed, I just remade the equation string like this:
NSString * newEquation = [equationElements componentsJoinedByString:#""];
While you could directly manipulate a string representation of a numeric value, such an approach is a bad idea. Not only is it less efficient than other alternatives, but potentially incorrect. (For example, #Ken's answer would result in two minus signs.)
What you probably want to do is negate the numeric value (just multiply it by -1, or subtract it from 0 as you suggested) and reflect that change in the interface (you mention a text box).
If you're using standard Cocoa controls (which inherit from NSControl, as NSTextField does) I suggest using -[NSControl setIntegerValue:] to change the text of the text field. If you (can) break up your UI well and have a text field for each variable in the quadratic equation, this should be fairly simple. (If you're using something other than an integer value, use something like -setDoubleValue: or -setFloatValue: instead.)
If you must create your own string beforehand, using an integer format specifier will display a "-" sign automatically if appropriate. Be sure to use %ld instead of %d (thanks, #Peter!) as the format specifier for NSInteger values to avoid possibly truncating values larger than 32-bit. For example:
NSString *result = [NSString stringWithFormat:#"%ld", nsIntegerValue];
In a more general sense, if you need to insert a dynamically-obtained string (not just something for which you can create a format string at compile time) you can also use an NSMutableString and its methods -appendString: and -insertString:atIndex: as well.