Objective C : Get correct float values(justified) - iphone

I worked a lot in it and can't find a solution. Even the title can't explain clearly.
I have three values weight, quantity and total
I had done the following
float wq = [[weightarray objectAtIndex:selectedint]floatValue];
float q = [quantity floatValue];
float total = wq * q;
for ex, if
[weightarray objectAtIndex:selectedint] = #"3.14";
quantity = 4;
then the result is
wq = 3.140000 q= 4.000000 total = 12.560000
but I need
wq = 3.14 total = 12.56
what to do?
I searched a lot, someone suggests to use NSDecimal,
NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:2 raiseOnExactness:FALSE raiseOnOverflow:TRUE raiseOnUnderflow:TRUE raiseOnDivideByZero:TRUE];
but the scale is not 2 here, wq value may have 3 or four numbers after point.
If the total = 2.30000100 means I need total = 2.300001
how to solve this?

I'm not entirely sure what it is your asking for, but it seems as if you want the values to only display a 2 d.p. In which case you could use a string format like so:
NSString *output = [NSString stringWithFormat:#"float = %.2f", 3.14];
The .2 specifies that the float should be justified to 2 d.p.
Hope this helps

There may be a more direct way to achieve it (which I don't know) but here's a suggestion...
Convert to string as you already do.
Use [myString hasSuffix:#"0"] to see if it ends in zero.
Use [myString substringToindex:[myString length]-1] to create a new string without the final zero.
Repeat.
I know it's not elegant, but unless someone has a better solution, this will at least do what you want.
UPDATE: scratch that - I just discovered [myString stringByTrimmingCharactersInSet:set]. Surely this must be what you need...?

Finally solution found, thanks to Martin
float total = 12.56000;
NSString *s = [NSString stringWithFormat:#"%f", total];
NSLog(#"%#",s);
BOOL success;
success =NO;
while(!success)
{
if ([s hasSuffix:#"0"])
{
s = [s substringWithRange:NSMakeRange(0,[s length]-1)];
}
else if ([s hasSuffix:#"."])
{
s = [s substringWithRange:NSMakeRange(0,[s length]-1)];
success = YES;
}
else
success = YES;
}
NSLog(#"%#",s);
if total = 12.560000 it returns total = 12.56
if total = 12.000000 it returns total = 12
if total = 10.000000 it returns total = 10
if total = 12.3000100 it returns total = 12.30001

Related

Obj-C, How do I handle version number with 4 parts?, greater than etc

I know this isn't going to be a challenging exercise, but I thought I'd ask, just in case there's some methods already in objective-c etc.
In my app I only handle a 2 number version number e.g. 1.5
I want to upgrade this to 4 numbers which could have up to 4 digits.
So I need to handle existing numbers and return true of false when passed database version and the bundle version numbers.
At the moment I simply do
NSString *strOnePointFive = #"1.5";
if (dblDBVersion < [strOnePointFive doubleValue]) {
}
This is a duplicate, was in other formats. Here are some answers to how to handle the version numbers, either equal, greater or below the required version number. Which is answer in this link..
NSString *reqSysVer = #"3.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
isSupported = YES;
else
isSupported = NO;
What I do is take that string and break it into components:
NSArray *array = [myVersion componentsSeparatedByCharactersInSet:#"."];
NSInteger value = 0;
NSInteger multiplier = 1000000;
for(NSString *n in array) {
value += [n integerValue] * multiplier;
multiplier /= 100;
}
What this does is give you a normalized value you can use for comparison, and will generally compare releases that have different "depths", ie 1.5 and 1.5.2.
It breaks if you have more than 100 point releases (ie any number is > 100) and also will declare 1.5.0 == 1.5. That said, its short, sweet, and simple to use.
EDIT: if you use the NSString 'compare:options:' method, make sure you have your string well groomed:
s1 = #"1.";
s2 = #"1";
NSLog(#"Compare %# to %# result %d", s1, s2, (int)[s1 compare:s2 options:NSNumericSearch]);
s1 = #"20.20.0";
s2 = #"20.20";
NSLog(#"Compare %# to %# result %d", s1, s2, (int)[s1 compare:s2 options:NSNumericSearch]);
2012-09-06 11:26:24.793 xxx[59804:f803] Compare 1. to 1 result 1
2012-09-06 11:26:24.794 xxx[59804:f803] Compare 20.20.0 to 20.20 result 1

How to round a float value with button

Okay so I'm trying to get my values rounded up to the nearest whole number with an IBAction.
So 1.88 -> 2.00 ,
11.40 -> 12.00 ,
111.01 -> 112.00, etc.
-
-(IBAction)roundUp:(id)sender
{
float floatRoundValue=lblTotalRound.text floatValue];
ceilf(floatRoundValue);
NSString *stringRoundValue = [NSString stringWithFormat:#"%1.0f", floatRoundValue];
lblTotalRound.text=stringRoundValue;
}
That's what I got. But it's still rounding down below .5 and to the nearest integer
(Ex. 1.19 -> 1 , i need 1.19 -> 2.00).
I've tried %1.2f but the value doesnt change at all.
What am I doing wrong?
ceilf doesn't modify the value you pass in. It returns a modified value.
floatRoundValue = ceilf(floatRoundValue);
ceilf is a function that returns a value (https://developer.apple.com/library/mac/#documentation/Darwin/Reference/Manpages/man3/ceil.3.html) , you simply need to change that line to the following.
floatRoundValue = ceilf(floatRoundValue);
So the complete code would in your case it would be something like this.
-(IBAction)roundUp:(id)sender
{
float floatRoundValue=lblTotalRound.text floatValue];
floatRoundValue = ceilf(floatRoundValue);
NSString *stringRoundValue = [NSString stringWithFormat:#"%1.0f", floatRoundValue];
lblTotalRound.text=stringRoundValue;
}
If you need to have a $ sign before :
-(IBAction)roundUp:(id)sender
{
float floatRoundValue=(lblTotalRound.text floatValue];
floatRoundValue = ceilf(floatRoundValue);
NSString *stringRoundValue = [NSString stringWithFormat:#"$%1.0f", floatRoundValue];
lblTotalRound.text=stringRoundValue;
}
NSString Class Reference

Format a String in IPhone

I need to add space after every 4 characters in a string.. For example if the string is aaaaaaaa, i need to format it as aaaa aaaa. I tried the following code, but it doesn't work for me.
NSMutableString *currentFormattedString = [[NSMutableString alloc] initWithString:formattedString];
int count = [formattedString length];
for (int i = 0; i<count; i++) {
if ( i %4 == 0) {
[currentFormattedString insertString:#" " atIndex:i];
}
}
Can anyone help me with this?
You haven't said what isn't working with your code, so it's hard to know exactly what to answer. As a tip - in future questions don't just say "it isn't working", but state WHAT isn't working and HOW it isn't working. However...
NSMutableString *currentFormattedString = [[NSMutableString alloc] initWithString:formattedString];
int count = [formattedString length];
for (int i = 0; i<count; i++) {
if ( i %4 == 0) {
[currentFormattedString insertString:#" " atIndex:i];
}
}
You are inserting a space, but you are not then accounting for this in your index value. So, suppose your formattedString is aaaaaaaaaaaaaaaa
The first time through your loop, you will get to the 4th position and insert a space at i=4
aaaa aaaaaaaaaaaa
Now the next time you get to insert a space, i will be 8. But the 8th position in your currentFormattedString isn't where you think it will be
aaaa aaa aaaaaaaaa
Next time it will be another 4 characters along which still isn't where you think
aaaa aaa aa aaaaaaa
And so on
You have to take into account the inserted space which will affect the offset value.
NSString *text = [[NSString alloc] initWithString:#"aaaaaaaa"];
NSString *result = [[NSString alloc] init];
double count = text.length/4;
if (count>1) {
for (int i = 0; i<count; i++) {
result = [NSString stringWithFormat:#"%#%# ",result,[text substringWithRange:NSMakeRange(i*4, 4)]];
}
result = [NSString stringWithFormat:#"%#%# ",result,[text substringWithRange:NSMakeRange(((int)count)*4, text.length-((int)count)*4)]];
}
else result = text;
I found the following which formats a string to a telephone number format, but it looks like you could easily change it to support other formats
Telephone number string formatting
Nick Bull answered on the reasons why your method broke already.
IMHO the appropriate solution would be to use a while loop and do the loop increments yourself.
NSInteger i = 4; // first #" " should be inserted after the 4th (index = 3) char
while (i < count) {
[currentFormattedString insertString:#" " atIndex:i];
count ++; // you did insert #" " so the length of the string increased
i += 5; // you now must skip 5 (" 1234") characters
}

Converting decimal to binary

I want to convert decimal number in binary number. I'm using this method:
- (NSMutableString*)intStringToBinary:(long long)element{
NSMutableString *str = [[NSMutableString alloc] initWithString:#""];
for(NSInteger numberCopy = element; numberCopy > 0; numberCopy >>= 1)
{
[str insertString:((numberCopy & 1) ? #"1" : #"0") atIndex:0];
}
return str;
}
everything is going fine if the number "element" is >0. If the number is <0 there is the problem. For examle the method can't convert the number "-1". What can i do to solve the problem? Thanks in advance!!
You need an extra bit for the sign.
Example:
1xxxx represents the binary number + xxxx.
0yyyy represents the binary number - yyyy.
Here is a way to do it in Python using Wallar's Algorithm. The input and output are lists.
from math import *
def baseExpansion(n,c,b):
j = 0
base10 = sum([pow(c,len(n)-k-1)*n[k] for k in range(0,len(n))])
while floor(base10/pow(b,j)) != 0: j = j+1
return [floor(base10/pow(b,j-p)) % b for p in range(1,j+1)]

Round division to upper integer

is there a simple way to round the result of a division to upper integer ?
I would like to have this :
18/20 -> 1
19/20 -> 1
20/20 -> 1
21/20 -> 2
22/20 -> 2
23/20 -> 2
... and so on ...
38/20 -> 2
39/20 -> 2
40/20 -> 2
41/20 -> 3
42/20 -> 3
43/20 -> 3
Must I manager with NSNumberFormatter stuff ?
I didn't success to get an integer value with that and have an integer comparison to do.
Thanks in advance !
int x, y;
int result = (x + (y-1)) / y;
testing:
int n = 20;
for (int i = 1; i <= 50; i++) {
NSLog(#"%d+(%d-1) / %d = %d", i, n, n, (i+(n-1))/n);
}
You use the standard ceil() and ceilf() functions available i math.h
Standard C supports double ceil(double x) and long double ceill(long double x). Perhaps the iPhone has these available? If your data is in integers in the first place, then you'll either have to find a clever trick or convert your ints to doubles first.
NSNumberFormatter is used when converting between numbers and strings. In addition to the c functions on primitives mentioned already, you can use NSDecimalNumber and NSDecimalNumberHandler to perform the calculation and rounding given instances of NSNumber. When in doubt, refer to the documentation. Number and Value Programming Guide
Sample code to divide, round up to the next integer and display the result.
NSDecimalNumber *denominator = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInteger:20] decimalValue]];
NSDecimalNumberHandler *numberHandler = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundUp scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:YES];
for (NSInteger counter = 1; counter <= 50; counter++) {
NSDecimalNumber *numerator = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithInteger:counter] decimalValue]];
NSDecimalNumber *result = [[numerator decimalNumberByDividingBy:denominator withBehavior:numberHandler] retain];
NSLog(#"%#/%# -> %d", numerator, denominator, [result integerValue]);
[result release];
}