NSNumber and decimal value - objective-c

I have an NSNumber like this for example = 1978, i would like to convert this for : 1K9, seconde example : 35700 convert to : 35K7 ( where "k" is kilometers and "M" is meters, how i can do this
thanks

int temp;
NSNumber *yourNumber;//the number you enter from some where
NSString *newValue;
if([yourNumber intValue]>1000){
temp = [yourNumber intValue] % 1000 ;//your number module 1000
newValue= [[temp stringValue]stringByAppendingString:#"K"];
}
Note: I haven't my mac with me, if the [temp stringValue] gives any worning&error please inform me.

Here's how:
NSNumber *initialNumber = [NSNumber numberWithInt:35700];
NSString *resultString = [NSString stringWithFormat:#"%iK%i", floor(initialNumber / 1000), floor((initialNumber % 1000) / 100)];

Basically you can work with the internal number data.
Assuming you are working on a meter-based value, you might want something like this:
NSNumber *sourceValue = ... // your NSNumber value from any source
int meters = sourceValue.intValue;
int km = floor(meters / 1000); // only your kilometers
int sub_km = meters % 1000; // only the part behind the kilometers
int first_sub_km = floor(sum_km / 100); // the first digit of the subrange
NSString *readable = [NSString stringWithFormat:#"%iK%i", km, first_sub_km];
First, you split the meters into <= 1000 and > 1000.
Then you'll just have to put that out formatted, with a K in between.

Write your own subclass of NSNumberFormatter. In this subclass you can implement the calculation logic.
The logic might look like this.
Devide the value by thousend and add your "k"
if you want to have the first digit of hundreds get the thired last digit of your value
return the new string

Related

How to get a CGFloat from a NSString?

In my current app, I have an equation that typically solves to a pretty long amount of decimal numbers, i.e: 0.12345 or .123 . But the way that I need this to work is to only show say 1 or 2 decimal numbers, so that would essentially produce 0.12 or 0.1 based on the values I mentioned.
In order to do this, I have done the following: Taken my CGFloat to a NSString:
CGFloat eX1 = 0.12345
NSLog(#" eX1 = %f", eX1); //This of course , prints out 0.12345
NSNumberFormatter *XFormatter = [[NSNumberFormatter alloc] init];
Xformatter.numberStyle=NSNumberFormatterDecimalStyle;
Xformatter.maximumFractionDigits=1;
NSString *eX1F = [formatter stringFromNumber:#(eX1)];
NSLog (#"eX1F = %#",eX1F); //This prints out 0.1
But my problem is that I need to keep working with this as a CGFloat after it has been formatted, I have tried taken the string back to a number by doing: numberFromString but the problem is that only works with a NSNumber.
What can I do to format my CGFloat and keep working with it as a CGFloat and not a NSString or NSNumber?
Update I have tried:
float backToFloat = [myNumber floatValue];
but the result is number unformatted : 0.10000 I need those extra 0s out
To convert NSString to a CGFloat you can use floatValue:
CGFloat *eX1rounded = [eX1F floatValue];
But you can round eX1 to eX1rounded directly without using a number formatter,
for example:
CFGloat *eX1rounded = roundf(eX1F * 10.0f)/10.0f;
In any case, you should keep in mind that numbers like 0.1 cannot be represented
exactly as a binary floating point number.
Use stringWithFormat: to round and convert to a string for display purposes:
NSString* str = [NSString stringWithFormat:#"%0.2f", eX1];
You can do the same thing in NSLog, the %0.2f says you want 2 decimal places.
NSLog(#" eX1 =%0.2f", eX1); // this prints "0.12"

Limiting Number of Decimals of an Output in Xcode 4.5

I have a few actions in xcode where the number of decimals in the output value needs to be limited to 3 decimal places out. What do I need to add to my code to achieve this task?
Here is an example of one of my actions:
- (IBAction)calculateMolarity:(id)sender {
float ourValue = [[_calcTextFieldNumOne text] floatValue] /[ [_calcTextFieldTwo text] floatValue];
NSNumber *ourNum =[NSNumber numberWithFloat:ourValue];
[_outputOfMolarity setText:[ourNum stringValue]];
NSString* formattedNumber = [NSString stringWithFormat:#"%.03f", ourNum];
here %.03f tells the formatter that you will be formatting a float
(%f) and, that should be rounded to three places, and should be padded
with 0's.
but you can do directly with your float ourValue like this
NSString* formattedNumber = [NSString stringWithFormat:#"%.03f", ourValue];
there is no need to convert your float value to NSNumber
you can use "%.3f" or "%.03f", no matter both gives same fromat
#"%.3f" = 1234.567
#"%.03f" = 1234.567 // which is equal to #"%.3f"

2 text fields to always equal 100 percent xcode

I have two text fields that are for percentages to be entered in. If i put 20 in the first field I would like the second text field to be updated to 60. And later on if I changed the second one to say 30, I would like the first updated to 70.
For ease of showing what I mean, say I have two text fields _firstPercent and _secondPercent with associated labels _firstTotal and _secondTotal:
float firstPercent = [_firstPercent.text floatValue];
float firstAmount = (firstSalePercent / 100) * firstOrigonalAmount;
_firstTotal.text = [NSString stringWithFormat:#"%1.0f",firstAmount];
float secondPercent = [_secondPercent.text floatValue];
float secondAmount = (secondSalePercent / 100) * secondOrigonalAmount;
_secondTotal.text = [NSString stringWithFormat:#"%1.0f",secondAmount];
I really don't know how to handle this so I tried adding this below its respective code. It works for the first one, but not the second.
float percentToSecond = 100 - firstPercent;
_secondPercent.text = [NSString stringWithFormat:#"%1.0f", percentToSecond];
float percentToFirst = 100 - secondPercent;
_firstPercent.text = [NSString stringWithFormat:#"%1.0f", percentToFirst];
I have tried other solutions but don't know what to do.
I would just like someone to lead me in the right direction.
Thanks
How about using the delegate method controlTextDidEndEditing: to see what value was entered, and then set the value for the other text field. In the following code tf1 and tf2 are the IBOutlets for the two text fields.
-(void)controlTextDidEndEditing:(NSNotification *)obj {
float value = [[[obj.userInfo valueForKey:#"NSFieldEditor"] string] floatValue];
if (obj.object == self.tf1) {
self.tf2.stringValue = [NSString stringWithFormat:#"%1.0f",100. - value];
}else if (obj.object == self.tf2) {
self.tf1.stringValue = [NSString stringWithFormat:#"%1.0f",100. - value];
}
}
You'd have to do some more checking to make sure the user didn't enter a number greater than 100 or something not a number.

parsing string into different kind of number string

I have a string called realEstateWorth with a value of $12,000,000.
I need this same string to remain a string but for any number (such as the one above) to be displayed as $12 MILLION or $6 MILLION. The point is it needs the words "MILLION" to come after the number.
I know there is nsNumberFormatter that can convert strings into numbers and vice versa but can it do what I need?
If anyone has any ideas or suggestions, it would be much appreciated.
Thank you!
So as I see it, you have two problems:
You have a string representation of something that's actually a number
You (potentially) have a number that you want formatted as a string
So, problem #1:
To convert a string into a number, you use an NSNumberFormatter. You've got a pretty simple case:
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterCurrencyStyle];
NSNumber *n = [f numberFromString:#"$12,000,000"];
// n is 12000000
That was easy! Now problem #2:
This is trickier, because you want a mixed spell-out style. You could consider using an NSNumberFormatter again, but it's not quite right:
[f setNumberStyle:NSNumberFormatterSpellOutStyle];
NSString *s = [f stringFromNumber:n];
// s is "twelve million"
So, we're closer. At this point, you could perhaps maybe do something like:
NSInteger numberOfMillions = [n integerValue] / 1000000;
if (numberOfMillions > 0) {
NSNumber *millions = [NSNumber numberWithInteger:numberOfMillions];
NSString *numberOfMillionsString = [f stringFromNumber:millions]; // "twelve"
[f setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString *formattedMillions = [f stringFromNumber:millions]; // "$12.00"
if ([s hasPrefix:numberOfMillionsString]) {
// replace "twelve" with "$12.00"
s = [s stringByReplacingCharactersInRange:NSMakeRange(0, [numberOfMillionsString length]) withString:formattedMillions];
// if this all works, s should be "$12.00 million"
// you can use the -setMaximumFractionDigits: method on NSNumberFormatter to fiddle with the ".00" bit
}
}
However
I don't know how well this would work in anything other than english. CAVEAT IMPLEMENTOR
Worst case scenario, you could implement a category on NSString to implement the behaviour you want.
In the method that you would do in that category you could take an NSNumberFormatter to bring that string to a number and by doing some modulo operation you could define if you need the word Million, or Billion, etc. and put back a string with the modulo for Million or other way you need it to be.
That way you could just call that method on your NSString like this :
NSString *humanReadable = [realEstateWorth myCustomMethodFromMyCategory];
And also.
NSString are immutable, so you can't change it unless you assign a new one to your variable.
I'd recommend storing this value as an NSNumber or a float. Then you could have a method to generate an NSString to display it like:
- (NSString*)numberToCurrencyString:(float)num
{
NSString *postfix = #"";
if (num > 1000000000)
{
num = num / 1000000000;
postfix = #" Billion";
}
else if (num > 1000000)
{
num = num / 1000000;
postfix = #" Million";
}
NSString *currencyString = [NSString stringWithFormat:#"%.0f%#", num, postfix];
return currencyString;
}
Note: Your question states that your input needs to remain a string. That's fine. So you'd need to 1.) first parse the number out of the string and 2.) then reconvert it to a string from a number. I've shown how to do step 2 of this process.

Odd behavior with NSUInteger - can't convert to float properly

Here is my situation. Its driving me nuts:
I have an NSMutableArray with a count value of 517. I have a double value that is my multiplier.
double multiplier = 0.1223;
double result = [myArray count] * multiplier; // 63 even (wrong!)
In fact it should be 63.2291. If I go:
double result = [myArray count] * 0.1223; // 63.2291 (right!)
or..
double result = 517 * multiplier; // 63.2291 (right!)
Does this make any sense to anyone?
Addendum:
here is my actual function:
- (double) getValueForPercentage:(double)percVal
{
int adjustedCount = [originalData count] - 1;
double final = percVal * (double)adjustedCount;
return final;
}
I never get any digits beyond the decimal point when I do this. It does however work if I get rid of the "-1", a-la:
- (double) getValueForPercentage:(double)percVal
{
int adjustedCount = [originalData count];
double final = percVal * (double)adjustedCount;
return final;
}
Of course, I need to have the -1.
Second addendum:
Another interesting thing I noted was, if I pass a hard-coded number to this function it works fine, but if I pass the double value that I need to use, it fails:
int pointCount = [srcData getDayCount];
for (int i = 0; i < pointCount; i++) {
double progress = (double)i/(double)(pointCount - 1);
double satv = [srcData getValueForPercentage:progress];
// satv is always a number without any digits beyond the decimal
}
Well, when I started to have these issues i looked around a bit and found no reason or explanation.
What I do now is make everything become an NSNumber and then call doubleValue on it. This should yield the results you're looking for:
NSNumber * pointCount = [NSNumber numberWithUnsignedInt: [srcData getDayCount]];
for (NSInteger i = 0; i < [pointCount intValue]; i++) {
NSNumber * count = [ NSNumber numberWithInt: i ];
double progress = [count doubleValue]/[pointCount doubleValue] - 1.0;
double satv = [srcData getValueForPercentage:progress];
// satv is always a number without any digits beyond the decimal
}
Hope it helps.