How to merge 2 NSStrings with a formatter? - ios

Merging these two strings:
#"###.##"
#"123"
Should output:
#"1.23"
I have developed a solution for this, but I'm looking for a simpler way, Using a NSNumberFormater, or some other API that I might be missing in Apple's documentation.
Thank you!
-
The solution as is right now, that I'm trying to get rid of:
/**
* User inputs a pure, non fractional, numeric string (e.g 1234) We'll see how many fraction digits it needs and format accordingly (e.g. 1234 produces a string such as '12.34' for 2 fractional digits. 12 will produce '0.12'.)
*
* #return The converted numeric string in an instance of NSDecimalNumber
*/
- (NSDecimalNumber *)decimalNumberFromRateInput
{
if (_numericInput == nil ||
_numericInput.length == 0) {
_numericInput = #"0";
}
[self clearLeadingZeros];
if (self.formatter == nil) {
return nil;
}
if (self.formatter.maximumFractionDigits == 0) {
return [NSDecimalNumber decimalNumberWithString:_numericInput];
}
else if (_numericInput.length <= self.formatter.maximumFractionDigits) {
NSString *zeros = #"";
for (NSInteger i = _numericInput.length; i < self.formatter.maximumFractionDigits ; i++) {
zeros = [zeros stringByAppendingString:#"0"];
}
NSString *decimalString = [NSString stringWithFormat:#"0.%#%#",zeros,_numericInput];
return [NSDecimalNumber decimalNumberWithString:decimalString];
}
else {
NSString *decimalPart = [_numericInput substringToIndex: _numericInput.length - self.formatter.maximumFractionDigits];
NSString *fractionalPart = [_numericInput substringFromIndex:_numericInput.length - self.formatter.maximumFractionDigits];
NSString *decimalString = [NSString stringWithFormat:#"%#.%#", decimalPart, fractionalPart];
return [NSDecimalNumber decimalNumberWithString: decimalString];
}
}

If I understand your goal correctly, the solution should be much simpler:
float number = [originalString floatValue] / 100.0;
NSString *formattedString = [NSString stringWithFormat:#"%.2f", number];

Related

Addition with leading zeros in number

I am receiving data in the form of a string from a database like so:
NSString *strTemp = #"000014";
I need to add 1 to the above,
like 000014 + 1 = 000015
000015 + 1 = 000016
depending on some count.
like:
for(int i =1; i < 5; i++)
{
int iTemp = [strTemp intValue] +i; // here i am getting 15 as int no not like 000015, 000016, 000017 ETC
}
I even tried NSString *strWarNo = [NSString stringWithFormat:#"%07d", iTemp]; but leading numbers may not be constant ...like string from db will be anything #"0023" or #"0000056".
I need to add one to while number, not only integer number.
How I can achieve this?
You can have a category over NSString to achieve this. I tried following code and its working fine.
.h of the category
#import <Foundation/Foundation.h>
#interface NSString (Arithematic)
- (NSString*)stringByAddingNumber:(NSInteger)number;
#end
.m of the category
#import "NSString+Arithematic.h"
#implementation NSString (Arithematic)
- (NSString*)stringByAddingNumber:(NSInteger)number
{
//To keep the width same as original string
int numberLength = (int)self.length;
NSInteger originalNumber = self.integerValue;
originalNumber += number;
NSString *resultString = [NSString stringWithFormat:#"%0*ld",numberLength,originalNumber];
return resultString;
}
#end
Usage:
NSString *strTemp = #"000014";
for(int i =1; i < 5; i++)
{
strTemp = [strTemp stringByAddingNumber:i];
}
NSLog(#"result %#",strTemp);
Hope this helps.
There is a simple way of doing this by converting string into NSInteger and then add your desired value into it and then convert the integer into string by appending you desired amount of zeros before then number.
-(NSString *)addNumber:(NSInteger)number toMyString:(NSString)myNum{
NSInteger numb = myString.integerValue;
numb += myNum;
NSString myNewString = [NSString stringWithFormat:#"0%d",myNewString];
return myNum;
}
If you want to format numbers with leading zeros then use NSNumberFormatter.
Store the number as a number (not a String) and then treat it like a number.
When you need to display it use an NSNumberFormatter to add leading zeros.
You can read more about NSNumberFormatter and adding leading zeros here... NSNumberFormatter leading 0's and decimals
Add which number you have to add in "num" and pass your number string "strNumber"
EX . [self addNumber:10 andYourString:#"000014"];
-(void)addNumber:(int)num andYourString:(NSString *)strNumber {
NSString * str_your_number = strNumber;
NSString * prevous_char = [NSString stringWithFormat:#"%c",
[str_your_number characterAtIndex:0]];
int number_zero = 0;
BOOL is_leading_zero = true;
for(int i = 0 ; i < str_your_number.length ; i++){
NSString *theCharacter = [NSString stringWithFormat:#"%c", [str_your_number characterAtIndex:i]];
if(is_leading_zero == true){
if([prevous_char isEqualToString:theCharacter]) {
number_zero++;
prevous_char = theCharacter;
}
else {
is_leading_zero = false;
}
}
NSLog(#"%#",theCharacter);
}
NSLog(#"%d",number_zero);
NSInteger you_numb = strNumber.integerValue;
you_numb += num;
NSString * str_zero = #"";
for(int j = 0 ; j < number_zero ; j++) {
str_zero = [str_zero stringByAppendingString:#"0"];
}
NSString * final_str = [NSString stringWithFormat:#"%#%ld",str_zero,(long)you_numb];
NSLog(#"%#",final_str);
}
it work...

How to convert this value into absolute value?

I am getting this from webservice
"rateavg": "2.6111"
now i am getting this in a string.
How to do this that if it is coming 2.6 it will show 3 and if it will come 2.4 or 2.5 it will show 2 ?
How to get this i am not getting. please help me
Try This
float f=2.6;
NSLog(#"%.f",f);
Hope this helps.
I come up with this, a replica of your query:
NSString* str = #"2.611";
double duble = [str floatValue];
NSInteger final = 0;
if (duble > 2.5) {
final = ceil(duble);
}else{
final = floor(duble);
}
NSLog(#"%ld",(long)final);
So it a case of using either ceil or floor methods.
Edit: Since you want it for all doubles:
NSString* str = #"4.6";
double duble = [str floatValue];
NSInteger final = 0;
NSInteger temp = floor(duble);
double remainder = duble - temp;
if (remainder > 0.5) {
final = ceil(duble);
}else{
final = floor(duble);
}
NSLog(#"%ld",(long)final);
check this
float floatVal = 2.6111;
long roundedVal = lroundf(floatVal);
NSLog(#"%ld",roundedVal);
plz use this
lblHours.text =[NSString stringWithFormat:#"%.02f", [yourstrvalue doubleValue]];
update
NSString *a =#"2.67899";
NSString *b =[NSString stringWithFormat:#"%.01f", [a doubleValue]];
// b will contane only one vlue after decimal
NSArray *array = [b componentsSeparatedByString:#"."];
int yourRating;
if ([[array lastObject] integerValue] > 5) {
yourRating = [[array firstObject] intValue]+1;
}
else
{
yourRating = [[array firstObject] intValue];
}
NSLog(#"%d",yourRating);
Try below code I have tested it and work for every digits,
NSString *str = #"2.7";
NSArray *arr = [str componentsSeparatedByString:#"."];
NSString *firstDigit = [arr objectAtIndex:0];
NSString *secondDigit = [arr objectAtIndex:1];
if (secondDigit.length > 1) {
secondDigit = [secondDigit substringFromIndex:1];
}
int secondDigitIntValue = [secondDigit intValue];
int firstDigitIntValue = [firstDigit intValue];
if (secondDigitIntValue > 5) {
firstDigitIntValue = firstDigitIntValue + 1;
}
NSLog(#"final result : %d",firstDigitIntValue);
Or another solution - little bit short
NSString *str1 = #"2.444";
float my = [str1 floatValue];
NSString *resultString = [NSString stringWithFormat:#"%.f",my]; // if want result in string
NSLog(#"%#",resultString);
int resultInInt = [resultString intValue]; //if want result in integer
To round value to the nearest integer use roundf() function of math.
import math.h first:
#import "math.h"
Example,
float ValueToRoundPositive;
ValueToRoundPositive = 8.4;
int RoundedValue = (int)roundf(ValueToRoundPositive); //Output: 8
NSLog(#"roundf(%f) = %d", ValueToRoundPositive, RoundedValue);
float ValueToRoundNegative;
ValueToRoundNegative = -6.49;
int RoundedValueNegative = (int)roundf(ValueToRoundNegative); //Output: -6
NSLog(#"roundf(%f) = %d", ValueToRoundNegative, RoundedValueNegative);
Read doc here for more information:
http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/roundf.3.html
NSString *value = #"1.23456";
float floatvalue = value.floatValue;
int rounded = roundf(floatvalue);
NSLog(#"%d",rounded);
if you what the round with greater value please use ceil(floatvalue)
if you what the round with lesser value please use floor(floatvalue)
You can round off decimal values by using NSNumberFormatter
There are some examples you can go through:
NSNumberFormatter *format = [[NSNumberFormatter alloc] init];
[format setPositiveFormat:#"0.##"];
NSLog(#"%#", [format stringFromNumber:[NSNumber numberWithFloat:25.342]]);
NSLog(#"%#", [format stringFromNumber:[NSNumber numberWithFloat:25.3]]);
NSLog(#"%#", [format stringFromNumber:[NSNumber numberWithFloat:25.0]]);
Corresponding results:
2010-08-22 15:04:10.614 a.out[6954:903] 25.34
2010-08-22 15:04:10.616 a.out[6954:903] 25.3
2010-08-22 15:04:10.617 a.out[6954:903] 25
NSString* str = #"2.61111111";
double value = [str doubleValue];
2.5 -> 3: int num = value+0.5;
2.6 -> 3: int num = value+0.4;
Set as your need:
double factor = 0.4
if (value < 0) value *= -1;
int num = value+factor;
NSLog(#"%d",num);

Remove negative symbol (-) from NSDecimalNumber gives me an error

I have an array with NSDecimalNumbers inside. I will do a check to see if that number is a negative number. If it is, I want to remove the negative sign (-). Here is my code:
NSString *amount = [myArray objectAtInde:2]; // Is a NSDecimalNumber with value of: -397.67
if ([amount doubleValue] < 0) {
amount = [amount stringByReplacingOccurrencesOfString:#"-" withString:#"- $"];
}
When I do that, I get the following error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSDecimalNumber stringByReplacingOccurrencesOfString:withString:]: unrecognized selector sent to instance 0x7fcaf94eff80'
Add below method in your source file
// multiplies number with -1 if it is less than zero else returns the same
- (NSDecimalNumber *)abs:(NSDecimalNumber *)num
{
if ([num compare:[NSDecimalNumber zero]] == NSOrderedAscending)
{
// Number is negative. Multiply by -1
NSDecimalNumber * negativeOne = [NSDecimalNumber decimalNumberWithMantissa:1
exponent:0
isNegative:YES];
return [num decimalNumberByMultiplyingBy:negativeOne];
}
else
{
return num;
}
}
And convert instance of NSDecimalNumbers to abs value without doing any type conversion as-
NSDecimalNumbers *number = [myArray objectAtInde:2];
number = [number abs:number];
the number returned will contain abs value in NSDecimalNumbers format.
Try this,
NSDecimalNumber *amountNumber = [myArray objectAtIndex:2]; // Is a NSDecimalNumber with value of: -397.67
NSString *stringWithDollarSymbol = [self addDollarSymoblForNumber:amountNumber];
You can assign the stringWithDollarSymbol to label
- (NSString *)addDollarSymoblForNumber:(NSDecimalNumber *)decimalNum
{
NSString *modifiedString = #"";
if (decimalNum) {
NSString *numberInStringForm = [decimalNum stringValue];
if ([decimalNum doubleValue] < 0) { //adds dollor symbol for negative numbers
modifiedString = [numberInStringForm stringByReplacingOccurrencesOfString:#"-" withString:#"- $"];
}
else //adds dollor symbol for positive numbers
{
modifiedString = [NSString stringWithFormat:#"$ %#",modifiedString];
}
}
return modifiedString;
}
EDIT
More Better Approach using NSNumberFormatter:
- (NSString *)formatNumberBasedOnCurrentLocale:(NSDecimalNumber *)number
{
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setLocale:[NSLocale currentLocale]];
[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];
NSString *result = [formatter stringFromNumber:number];
if (result.length >0) {
return result;
}
return nil;
}
Please add line,
if ([amount doubleValue] < 0) {
amount=[NSString stringWithFormat:#"%#",[myArray objectAtIndex:2]];//add line
amount = [amount stringByReplacingOccurrencesOfString:#"-" withString:#""];
}
it may be work for you,
I just used your code & it's working fine at my end.
Tried below thing,
NSString *amount = #"-397.67";//[myArray objectAtInde:2]; // Is a NSDecimalNumber with value of: -397.67
if ([amount doubleValue] < 0) {
amount = [amount stringByReplacingOccurrencesOfString:#"-" withString:#""];
}
Try it at your end.
If nothing will work then multiply your negative float value with -1 & you will get positive number. If that is your requirement.
Your [myArray objectAtInde:2] is a NSDecimalNumber rather than NSString, try this:
NSDecimalNumber *amountNumber = [myArray objectAtInde:2];
NSString *amount = [NSString stringWithFormat:#"%#", amountNumber];
Maybe you should try this one:
NSString *amount = #(ABS([myArray[2] doubleValue])).stringValue ; // Is a NSDecimalNumber with value of: -397.67
If your intention is to rescue from the negative then just simply convert the value into an absolute value.
NSString *amount = [myArray objectAtIndex:2]; // Is a NSDecimalNumber with value of: -397.67
NSLog(#"The value is : %#",[NSString stringWithFormat:#"%.2f", fabs([amount doubleValue])]);
The value is: 397.67

How to calculate number of digits after floating point in iOS?

How can I calculate the number of digits after the floating point in iOS?
For example:
3.105 should return 3
3.0 should return 0
2.2 should return 1
Update:
Also we need to add the following example. As I want to know number of digits in the fraction part.
1e-1 should return 1
Try this way:
NSString *enteredValue=#"99.1234";
NSArray *array=[enteredValue componentsSeparatedByString:#"."];
NSLog(#"->Count : %ld",[array[1] length]);
What I used is the following:
NSString *priorityString = [[NSNumber numberWithFloat:self.priority] stringValue];
NSRange range = [priorityString rangeOfString:#"."];
int digits;
if (range.location != NSNotFound) {
priorityString = [priorityString substringFromIndex:range.location + 1];
digits = [priorityString length];
} else {
range = [priorityString rangeOfString:#"e-"];
if (range.location != NSNotFound) {
priorityString = [priorityString substringFromIndex:range.location + 2];
digits = [priorityString intValue];
} else {
digits = 0;
}
}
Maybe there is a more elegant way to do this, but when converting from a 32 bit architecture app to a 64 bit architecture, many of the other ways I found lost precision and messed things up. So here's how I do it:
bool didHitDot = false;
int numDecimals = 0;
NSString *doubleAsString = [doubleNumber stringValue];
for (NSInteger charIdx=0; charIdx < doubleAsString.length; charIdx++){
if ([doubleAsString characterAtIndex:charIdx] == '.'){
didHitDot = true;
}
if (didHitDot){
numDecimals++;
}
}
//numDecimals now has the right value

Removing unnecessary zeros in a simple calculator app

I made a simple calculator and Everytime I hit calculate it'll give a an answer but gives six unnecessary zeros, my question, how can I remove those zeros?
NSString *firstString = textfieldone.text;
NSString *secondString = textfieldtwo.text;
NSString *LEGAL = #"0123456789";
NSCharacterSet *characterSet = [[NSCharacterSet characterSetWithCharactersInString:LEGAL] invertedSet];
NSString *filteredOne = [[firstString componentsSeparatedByCharactersInSet:characterSet]
componentsJoinedByString:#""];
NSString *filteredTwo = [[secondString componentsSeparatedByCharactersInSet:characterSet]
componentsJoinedByString:#""];
firstString = filteredOne;
secondString = filteredTwo;
//Here we are creating three doubles
double num1;
double num2;
double output;
//Here we are assigning the values
num1 = [firstString doubleValue];
num2 = [secondString doubleValue];
output = num1 + num2;
label.text = [NSString stringWithFormat:#"%f",output];
Example:
15 + 15 = 30.000000
I want to add that none of that is necessary if you use the %g specifier.
If you're displaying this by using a string, check the following approaches.
NSString
NSString * display = [NSString stringWithFormat:#"%f", number];
//This approach will return 30.0000000
NSString * display = [NSString stringWithFormat:#"%.2f", number];
//While this approach will return 30.00
Note: You can specify the number of decimals you want to return by adding a point and a number before the 'f'
-Edited-
In your case use the following approach:
label.text = [NSString stringWithFormat:#"%.0f", output];
//This will display your result with 0 decimal places, thus giving you '30'
Please try this out. This should suit your requirements completely.
NSString * String1 = [NSString stringWithFormat:#"%f",output];
NSArray *arrayString = [String1 componentsSeperatedByString:#"."];
float decimalpart = 0.0f;
if([arrayString count]>1)
{
decimalpart = [[arrayString objectAtIndex:1] floatValue];
}
//This will check if the decimal part is 00 like in case of 30.0000, only in that case it would strip values after decimal point. So output will be 30
if(decimalpart == 0.0f)
{
label.text = [NSString stringWithFormat:#"%.0f", output];
}
else if(decimalpart > 0.0f) //This will check if the decimal part is 00 like in case of 30.123456, only in that case it would shows values upto 2 digits after decimal point. So output will be 30.12
{
label.text = [NSString stringWithFormat:#"%.02f",output];
}
Let me know if you need more help.
Hope this helps you.

Resources