Calculator rounding too much - objective-c

I have this code written for a calculator application for an iPad but I just could not find a way for it to solve numbers in decimal. When I try to solve for example: 4.5 + 0.5, it will give me just 4 for an answer. I know that there is something missing with this.
Thanks for those incoming responses.
Cheers in advance!
- (IBAction)equalsPressed {
self.typingNumber = NO;
self.secondNumber = [self.calculatorDisplay.text intValue];
int result = 0;
if ([self.operation isEqualToString:#"+"]) {
result = self.firstNumber + self.secondNumber;
}
else if ([self.operation isEqualToString:#"-"]) {
result = self.firstNumber - self.secondNumber;
}
else if ([self.operation isEqualToString:#"*"]) {
result = self.firstNumber * self.secondNumber;
}
else if ([self.operation isEqualToString:#"/"]) {
result = self.firstNumber / self.secondNumber;
}
self.calculatorDisplay.text = [NSString stringWithFormat:#"%2.d", result];
self.displayLabel.text = self.calculatorDisplay.text;
}
- (IBAction) clearPressed: (id)sender {
self.calculatorDisplay.text = #"";
self.firstNumber = [self.calculatorDisplay.text intValue];
self.operation = [sender currentTitle];
}
- (IBAction)backspaceButton: (id)sender {
self.displayLabel.text = [self.displayLabel.text substringToIndex:self.displayLabel.text.length - 1];
}
- (IBAction)decimalPressed:(id)sender {
NSString *currentText = self.displayLabel.text;
if ([currentText rangeOfString:#"." options:NSBackwardsSearch].length == 0) {
self.displayLabel.text = [self.displayLabel.text stringByAppendingString:#"."];
}
}

You wrote:
int result = 0;
Change int to double.
Change all uses of intValue to doubleValue.
Change the format string from #"%2.d" to #"%2.f".

You've declared result to be an integer on this line:
int result = 0;
This is causing the values to be rounded, in some way. I'd also double check that other values that you use are of the right type too. If the input values are also ints you'd be calculating int(4.5) + int(0.5) which is 4 + 0 which is just 4.
If you change this to a float or double (depending on your needs) it should work better. Like so:
float result = 0;

Related

How to get the correct value and type of NSNumber?

I am creating an NSNumber from string by check if the string is float or int using NSNumberFormatter. I want to have a method to return what type the NSNumber holds and the correct value. It works for int, but not working for decimal numbers.
NSNumber *n;
enum CFNumberType _numberType;
- (instancetype)initWithString:(NSString *)string {
self = [super init];
if (self) {
NSNumberFormatter *formatter = [NSNumberFormatter new];
decimalPattern = #"\\d+(\\.\\d+)";
if ([Utils matchString:string withPattern:decimalPattern]) {
// Float
formatter.numberStyle = NSNumberFormatterDecimalStyle;
_numberType = kCFNumberDoubleType;
n = [formatter numberFromString:string];
} else {
// Integer
formatter.numberStyle = NSNumberFormatterNoStyle;
_numberType = kCFNumberIntType;
n = [formatter numberFromString:string];
}
self = [self initWithNumber:n];
}
return self;
}
- (CFNumberType)value {
CFNumberType num; // How to determine the type of num?
CFNumberGetValue((CFNumberRef)n, _numberType, &num);
return num;
}
- (CFNumberType)numberType {
return _numberType;
}
In the value method, if I specify float num, then it works for floating point. But I cannot use float because I want to make it work for int as well. How to do this?
I have found a solution for this. First check if the number is double and call the appropriate value method.
- (BOOL)isDouble {
if (_numberType == kCFNumberFloatType || _numberType == kCFNumberFloat32Type || _numberType == kCFNumberFloat64Type || _numberType == kCFNumberDoubleType) {
return YES;
}
return NO;
}
- (double)doubleValue {
if ([self isDouble]) {
return [n doubleValue];
}
return 0.0;
}
- (int)intValue {
if (![self isDouble]) {
return [n intValue];
}
return 0;
}

Objective C weird IF syntax

As having most of my experience in PHP, I have seen lots of new syntax rules. Most of them I have accepted and understood, but there is one that just makes no sense to me.
currentNumber = 0;
self.Label.text = [NSString stringWithFormat:#"%2.0f", result];
if ([sender tag] == 0) result = 0; {
currentOperation = (int)[sender tag];
}
As you can see, there is a bracket after result = 0;. At first I thought it was just a shortcut, just like [[something alloc]init], but when I rewrote the code like this:
currentNumber = 0;
self.Label.text = [NSString stringWithFormat:#"%2.0f", result];
if ([sender tag] == 0) result = 0;
else{
currentOperation = (int)[sender tag];
}
my app was not behaving as intended, even though the above has no syntax errors.
So my question is, what does this syntax mean? How does it translate to PHP if it even does?
This is not a single if statement, it is an if followed by a sequence of statements enclosed in curly braces. A better way of formatting this would be as follows:
if ([sender tag] == 0)
result = 0;
// ---- if statement ends here ----
{
currentOperation = (int)[sender tag];
}
result = 0 is the only part that is done conditionally; the rest, i.e.
currentOperation = (int)[sender tag];
is done unconditionally. In fact, the block that follows the conditional could be rewritten without curly braces; this would not change its behavior:
if ([sender tag] == 0)
result = 0;
currentOperation = (int)[sender tag];
why enclose currentOperation = (int)[sender tag]; within curly braces?
There is no point in doing that. The intention may have been to enclose both result = 0 and currentOperation = ... in the same block, but whoever wrote this code has made a typo.
if ([sender tag] == 0) result = 0; {
currentOperation = (int)[sender tag];
}
is equivalent to:
if ([sender tag] == 0) { result = 0; } {
currentOperation = (int)[sender tag];
}
which is equivalent to:
if ([sender tag] == 0) {
result = 0;
}
currentOperation = (int)[sender tag];
In other words, in your code only result = 0; is conditional - the rest is executed always.

Remove zeros from country code of phone number in Objective-C

I want to remove the preceding zeros from phone number's country code.
I take it as NSString because phone number contains symbols such as + , ( , ) , - .
I need those symbols.
e.g
Input:-
1) NSString *phNo = #"0011234567890";
2) NSString *phNo2 = #"0601234567999";
Output:-
1) 11234567890
2) 601234567999
What I did is as follows
if ([phNo length]>10) {
NSString *countryCodeSubString = [phNo substringToIndex:[phNo length]-10];
if ([[countryCodeSubString substringToIndex:1]isEqualToString:#"0"]) {
for (int i=0; i<[countryCodeSubString length]; i++) {
NSString *str = [countryCodeSubString substringToIndex:i];
if ([str isEqualToString:#"0"]) {
str = [str stringByReplacingOccurrencesOfString:#"0" withString:#""];
}
}
}
}
I know above code is wrong.
Can anybody help me with this ? How can I do this efficiently ?
int firstNonZeroCharIndex = -1;
for (int i=0; i<phNo.length; ++i) {
if ([phNo.characterAtIndex:i] != '0') {
firstNonZeroCharIndex = i;
break;
}
}
if (firstNonZeroCharIndex != -1) {
phNo = [phNo subStringFromIndex:firstNonZeroCharIndex];
}
If you just want to get the preceding zeroes off, then you can do simply like this.
NSString *phNo = #"0011234567890";
float number = [phNo floatValue];
NSString *phNoWithOutZero = [NSString stringWithFormat:#"%1.0f", number];
But this will not work it the string have any special characters except number.

Comparing count of an NSArray with an integer value leads to incorrect code execution

I am facing a peculiar issue in an iPhone program. This is my code -
In the viewDidLoad of my view controller I create an array
grades = [[NSArray arrayWithObjects:#"Grade 1", #"Grade 2", #"Grade 3", nil] retain];
Now I have a property
#property (nonatomic) NSInteger selectedGradeIndex;
And I wrote the following setter method
- (void) setSelectedGradeIndex:(NSInteger)newValue
{
if(newValue >= [grades count])
{
NSLog(#"newValue = %d >= [grades count] = %d",newValue, [grades count]);
newValue = 0;
}
else if(newValue < 0)
{
NSLog(#"newValue = %d < 0",newValue);
newValue = [grades count] - 1;
}
selectedGradeIndex = newValue;
lblGrade.text= [grades objectAtIndex:selectedGradeIndex];
}
Somewhere in the code I have
self.selectedGradeIndex = -1;
The log inside the setter shows
newValue = -1 >= [grades count] = 6
I am confused. Why will the control go inside the first if condition when the log clearly shows that the condition is false.
I changed the setter to
- (void) setSelectedGradeIndex:(NSInteger)newValue
{
int count = [grades count];
if(newValue >= count)
{
NSLog(#"newValue = %d >= count = %d",newValue, count);
newValue = 0;
}
else if(newValue < 0)
{
NSLog(#"newValue = %d < 0",newValue);
newValue = count - 1;
}
selectedGradeIndex = newValue;
lblGrade.text= [grades objectAtIndex:selectedGradeIndex];
}
And now everything works as expected. The log is
newValue = -1 < 0
Can some tell me why is the earlier method failing?
When you compare a signed int (your variable) with an unsigned int (the type of -[NSArray count], the signed int is promoted to an unsigned. The number -1 translates to an extremely large unsigned int. Thus, -1 > 6.

How to write a condition for float value?

Hi im working with sqlite.
stringFloat1 = [pediDetails.doseTo FloatValue];
float mulWith1 = [appDelegate.selectedWeight FloatValue];
NSLog(#"mulwith1:%f",mulWith1);
//if(mulWith1 =0.00) {
// int temp1=0;
//}
// else {
float temp1 = stringFloat1*mulWith1;
NSString *setWeight;
NSLog(#"temp1:%f",temp1);
// }
//float temp1;
//NSString *setWeight = [NSString stringWithFormat:#"%.02f",temp,temp1];
//if(temp1=0.00) {
//setWeight = [NSString stringWithFormat:#"%.02f",temp];
//}
//else{
setWeight = [NSString stringWithFormat:#"%.02f-%.02f",temp,temp1];
What i need is,if temp1 is 0.00,then only temp value should be displayed.What is the condition?
Use
if(temp1==0.00)
{
setWeight = [NSString stringWithFormat:#"%.02f",temp];
}
Instead of
if(temp1=0.00)
{
setWeight = [NSString stringWithFormat:#"%.02f",temp];
}