intValue is missing decimals - iphone

I have a price that I need to convert based on the selected currency.
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"currency.plist"];
NSDictionary *plistDictionary = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];
int price = [price intValue];
int currencyValue = [[plistDictionary valueForKey:#"EUR"] intValue];
int convertedCurrency = (price / currencyValue);
price is an NSNumber and the valueForKey is also a number from a plist file I have setup with conversion rates.
The problem I am having, is that my price is missing the decimals. Everytime I get the intValue from the price it's just rounded up or down. The same issue exists for the exchange rate I get from the plist.
I have looked into NSNumberFormatter but it won't let me setFormat for the NSNumberFormatter. Any advice, please?

int is an integer type - by definition it does not have a decimal value. Instead try:
float fprice = [price floatValue];
float currencyValue = [[plistDictionary valueForKey:#"EUR"] floatValue];
float convertedCurrency = (fprice / currencyValue);

intValue returns an integer, which (by definition) is rounded to a number without decimals.
You could use doubleValue, which returns a double (which does have the fractional portion) or decimalValue which returns a NSDecimal object.

Take the price string and remove the period. After that convert the NSString to and int, which means you end up with 4235 pennies (or 42 dollars and 35 cents). (Also, make sure that the price string you're getting has two decimal places! Some people are lazy, and output "3.3" for "$3.30".)
NSString *removePeriod = [price stringByReplacingOccurrencesOfString:#"." withString:#""];
int convertedPrice = [removePeriod intValue];
float exchangeRate;
Then get the exchange rates depending on which currency has been selected and use the following code:
int convertedCurrency = round((double)convertedPrice / exchangeRate);
addCurrency = [NSString stringWithFormat: #"%0d.%02d", (convertedCurrency / 100), (convertedCurrency % 100)];
addCurrency is your final price.

To deal with the exact number of deciamlas and if all your currencies have 2 decimal places (e.g not JPY) make all numbers the number of cents
e.g. store 43.35 EUR as 4235.
Then you can use in arithmetic and then just deal with formatting using value/100.0 and NSNumberFormatter

Related

Elegant method to omit fraction formatting number if number is an integer

I am formatting floating point numbers and right now I have the %0.2f formatter, but I'd like to omit the .00 if the floating point number is an even integer.
Of course I can think of string replacing the .00, but that's crude.
I found that the description of NSNumber also does something similar:
NSNumber *number = [NSNumber numberWithFloat:_paragraphSpacing];
[retString appendFormat:#"margin-bottom:%#px;", number];
This this does hover not limit the post comma digits. if the number is 1234.56789 then the description will output that.
So my question is, is there a just as simple way - possibly without having to create an NSNumber object - to achieve this result?
Since floating-point numbers aren't exact, there's no guarantee that your number will actually be an integer. You can, however, check if it's within a reasonably small distance from an integer value. And of course you don't need an NSNumber for this. (Generally speaking, NSNumber is not used for formatting, its purpose is representing a primitive C type, either integral or floating-point types, using an Objective-C object.)
#include <math.h>
- (NSString *)stringFromFloat:(float)f
{
const float eps = 1.0e-6;
if (abs(round(f) - f) < eps) {
// assume an integer
return [NSString stringWithFormat:#"margin-bottom: %.0fpx", round(f)];
} else {
// assume a real number
return [NSString stringWithFormat:#"margin-bottom: %.2fpx", f];
}
}
Use a formatter:
NSNumberFormatter* formatter= [NSNumberFormatter new];
formatter.numberStyle= NSNumberFormatterDecimalStyle;
formatter.maximumFractionDigits=2;
NSNumber *number = [NSNumber numberWithFloat:_paragraphSpacing];
[retString appendFormat:#"margin-bottom:%#;", [formatter stringFromNumber: number]];
You can use an NSNumberFormatter for this:
static NSNumberFormatter *numberFormatter = nil;
if (numberFormatter == nil) {
numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.minimumFractionDigits = 0;
numberFormatter.maximumFractionDigits = 2;
numberFormatter.usesGroupingSeparator = NO;
}
NSString *formattedNumberString = [numberFormatter
stringForNumber:[NSNumber numberWithDouble: _paragraphSpacing]];
You can use C function modff to get the fraction part and test it:
float fractionPart = 0.;
modff(_paragraphSpacing, &fractionPart);
if( fabsf(fractionPart) < 0.01 ) {
// format as integer
[retString appendFormat:#"margin-bottom:%d", (int)_paragraphSpacing];
} else {
// format as float
[retString appendFormat:#"margin-bottom:%0.2f", _paragraphSpacing];
}

iphone NSString stringWithFormat and float

I have an input with UIKeyboardTypeDecimalPad and I need my user to input a float (with unlimited characters after a dot). After the input I filter the string with :
NSString *newValue = [NSString stringWithFormat:#"%.f",[textField.text floatValue]]
But that gives me a lot of unnecessary digits after a dot (for example for 2.25 it gives 2.249999).
All I need is to filter the input so it'll be a legal float (digits and not more than one dot).
How do I do that?
NSString *newValue = [NSString stringWithFormat:#"%0.1f", [textField.text floatValue]];
the number after the dot is the number of decimal places you want.
UPDATE:
You could use string manipulation to determine the number of decimal places the user typed in (don't forget to check for edge cases):
NSInteger numberOfDecimalPlaces = textString.length - [textString rangeOfString:#"."].location - 1;
and then if you want to create a new string with a new float to the same level of display precision you could use:
NSString *stringFormat = [NSString stringWithFormat:#"%%0.%if", numberOfDecimalPlaces];
NSString *newString = [NSString stringWithFormat:stringFormat, newFloat];
Not sure if this is what you want but try something like the following:
NSNumberFormatter *nf = [[NSNumberFormatter alloc] init];
// set to long number of decimals to accommodate whatever a user might enter
[nf setMaximumFractionDigits:20];
NSString *s = [nf stringFromNumber:
[NSNumber numberWithDouble:[userEnteredNumberString doubleValue]]
];
NSLog(#"final:%#",s);
Try using a double instead of float. I think the double removes all trailing zero's.

Can we assign exact string value to an int value in iphone sdk

In my application I have a value like "25:30" in NSString and I want to assign this value to int value.
If I do like:
int j = [stringval intValue];
hence I got the value "25" to my int value but I want the full value.
Is it possible?
If you mean 25.30 then you need floats, use CGFloat j = [stringval floatValue];
If that is supposed to be minutes & seconds, use NSDateFormatter's dateFromString:.
You can try this
NSString *new = #"25:30";
NSArry *data = [new componentsSeparatedByString:#":"];
int first = [[data objectAtIndex:0] intValue]; \\\ 25
int second = [[data objectAtIndex:1] intValue]; \\\ 30

Unable to convert string value into float

when i convert a string value into float it takes o.oooo. here is the code.
NSString *amt=txtTotalBill.text;
NSLog(#"%#",amt);
float amount = [amt floatValue]
NSLog(#"%f",amount);
NSString *insertData=[NSString stringWithFormat:#"insert into tbl_Bills(Amount,Note,Due_On) values ('%f')",amount];
[database executeQuery:insertData];
NSLog(#"inert query: %#",insertData);
NSLog(#"value inserted");
[table reloadData];
[database close];
everytime it takes amount as 0.0000.In this code amt value is correct but that string value doesnt convert into float.
just tried some of your codeblock and it works out fine for me. The error could be in the NSString itself. Perhaps its not passing in a totally numerical number. Try using a CGFloat as well, although this shouldn't change anything.
I assume you've alreayd ensured that no non-numeric characters can make their way into the NSString thats to be converted.
Can you let us know whats the output you got for the NSLog for the string?
Could you also try setting an output format for the float? e.g. '%3.3f' will display 3 numbers each before and after the decimal point.
Check txtTotalBill.text if the text is float number format.
If text is not float number format, [NSString floatValue] retuns 0.00000
Try this, i think this will work.
float amount = [txtTotalBill.text floatValue];
This works perfect
NSString *amt = txtTotalBill.text;
float amount;
amount = [amt floatValue];

Decimal point adjustment for string in iPhone

I want to display a number in decimal format only if the number is not an integer. Like if the number is float it must be displayed with one decimal point. But if the number is an integer it must be displayed without a decimal point like its shown in the following link(second part of the code)
http://www.csharp-examples.net/string-format-double/
I am using a string like
NSString *temp =[NSString stringWithFormat:#"0.1f" , 10];
this temp is 10.0 I want it to be 10 but if I am doing as follows
NSString *temp =[NSString stringWithFormat:#"0.1f" , 10.9];
then it must be like 10.9
How to resolve this in iPhone.
You could check the value of the string against a cast, then format the string accordingly:
float x = 42.1; // whatever
long x_int = x;
bool is_integer = x_int == x;
NSString* temp = nil;
if (is_integer)
{
temp = [NSString stringWithFormat:#"%d", x_int];
}
else
{
temp = [NSString stringWithFormat:#"%0.1f", x];
}
I got the solution,
NSString *temp =[NSString stringWithFormat:#"%g" , 10.9];