How to calculate number of digits after floating point in iOS? - 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

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 a NSString to NSInteger with the sum of ASCII values?

In my Objective-C code I'd like to take a NSString value, iterate through the letters, sum ASCII values of the letters and return that to the user (preferably as the NSString too).
I have already written a loop, but I don't know how to get the ASCII value of an individual character. What am I missing?
- (NSString*) getAsciiSum: (NSString*) input {
NSInteger sum = 0;
for (NSInteger index=0; index<input.length; index++) {
sum = sum + (NSInteger)[input characterAtIndex:index];
}
return [NSString stringWithFormat: #"%#", sum];
}
Note: I've seen similar questions related to obtaining ASCII values, but all of them ended up displaying the value as a string. I still don't know how to get ASCII value as NSInteger.
Here is the answer:
- (NSString *) getAsciiSum: (NSString *) input
{
NSString *input = #"hi";
int sum = 0;
for (NSInteger index = 0; index < input.length; index++)
{
char c = [input characterAtIndex:index];
sum = sum + c;
}
return [NSString stringWithFormat: #"%d", sum]);
}
This is working for me.
Hope this helps!
This should work.
- (NSInteger)getAsciiSum:(NSString *)stringToSum {
int asciiSum = 0;
for (int i = 0; i < stringToSum.length; i++) {
NSString *character = [stringToSum substringWithRange:NSMakeRange(i, 1)];
int asciiValue = [character characterAtIndex:0];
asciiSum = asciiSum + asciiValue;
}
return asciiSum;
}
Thank you to How to convert a NSString to NSInteger with the sum of ASCII values? for the reference.

Find substring range of NSString with unicode characters

If I have a string like this.
NSString *string = #"😀1😀3😀5😀7😀"
To get a substring like #"3😀5" you have to account for the fact the smiley face character take two bytes.
NSString *substring = [string substringWithRange:NSMakeRange(5, 4)];
Is there a way to get the same substring by using the actual character index so NSMakeRange(3, 3) in this case?
Thanks to #Joe's link I was able to create a solution that works.
This still seems like a lot of work for just trying to create a substring at unicode character ranges for an NSString. Please post if you have a simpler solution.
#implementation NSString (UTF)
- (NSString *)substringWithRangeOfComposedCharacterSequences:(NSRange)range
{
NSUInteger codeUnit = 0;
NSRange result;
NSUInteger start = range.location;
NSUInteger i = 0;
while(i <= start)
{
result = [self rangeOfComposedCharacterSequenceAtIndex:codeUnit];
codeUnit += result.length;
i++;
}
NSRange substringRange;
substringRange.location = result.location;
NSUInteger end = range.location + range.length;
while(i <= end)
{
result = [self rangeOfComposedCharacterSequenceAtIndex:codeUnit];
codeUnit += result.length;
i++;
}
substringRange.length = result.location - substringRange.location;
return [self substringWithRange:substringRange];
}
#end
Example:
NSString *string = #"😀1😀3😀5😀7😀";
NSString *result = [string substringWithRangeOfComposedCharacterSequences:NSMakeRange(3, 3)];
NSLog(#"%#", result); // 3😀5
Make a swift extension of NSString and use new swift String struct. Has a beautifull String.Index that uses glyphs for counting characters and range selecting. Very usefull is cases like yours with emojis envolved

NSString to treat "regular english alphabets" and characters like emoji or japanese uniformly

There is a textView in which I can enter Characters. characters can be a,b,c,d etc or a smiley face added using emoji keyboard.
-(void)textFieldDidEndEditing:(UITextField *)textField{
NSLog(#"len:%lu",textField.length);
NSLog(#"char:%c",[textField.text characterAtIndex:0]);
}
Currently , The above function gives following outputs
if textField.text = #"qq"
len:2
char:q
if textField.text = #"😄q"
len:3
char:=
What I need is
if textField.text = #"qq"
len:2
char:q
if textField.text = #"😄q"
len:2
char:😄
Any clue how to do this ?
Since Apple screwed up emoji (actually Unicode planes above 0) this becomes difficult. It seems it is necessary to enumerate through the composed character to get the actual length.
Note: The NSString method length does not return the number of characters but the number of code units (not characters) in unichars. See NSString and Unicode - Strings - objc.io issue #9.
Example code:
NSString *text = #"qqq😄rrr";
int maxCharacters = 4;
__block NSInteger unicharCount = 0;
__block NSInteger charCount = 0;
[text enumerateSubstringsInRange:NSMakeRange(0, text.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
unicharCount += substringRange.length;
if (++charCount >= maxCharacters)
*stop = YES;
}];
NSString *textStart = [text substringToIndex: unicharCount];
NSLog(#"textStart: '%#'", textStart);
textStart: 'qqq😄'
An alternative approach is to use utf32 encoding:
int byteCount = maxCharacters*4; // 4 utf32 characters
char buffer[byteCount];
NSUInteger usedBufferCount;
[text getBytes:buffer maxLength:byteCount usedLength:&usedBufferCount encoding:NSUTF32StringEncoding options:0 range:NSMakeRange(0, text.length) remainingRange:NULL];
NSString * textStart = [[NSString alloc] initWithBytes:buffer length:usedBufferCount encoding:NSUTF32LittleEndianStringEncoding];
There is some rational for this in Session 128 - Advance Text Processing from 2011 WWDC.
This is what i did to cut a string with emoji characters
+(NSUInteger)unicodeLength:(NSString*)string{
return [string lengthOfBytesUsingEncoding:NSUTF32StringEncoding]/4;
}
+(NSString*)unicodeString:(NSString*)string toLenght:(NSUInteger)len{
if (len >= string.length){
return string;
}
NSInteger charposition = 0;
for (int i = 0; i < len; i++){
NSInteger remainingChars = string.length-charposition;
if (remainingChars >= 2){
NSString* s = [string substringWithRange:NSMakeRange(charposition,2)];
if ([self unicodeLength:s] == 1){
charposition++;
}
}
charposition++;
}
return [string substringToIndex:charposition];
}

How to merge 2 NSStrings with a formatter?

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];

Resources