String of float to an arbitrary decimal precision - objective-c

I want to write a method that takes a given float, a precision, and formats it such that it displays the given precision number of decimal places.
Of course, this method also does other bunch of things.
Right now, I have
[NSString stringWithFormat:#"0%.3f", s]; //s is the float argument
Which gives the string of the float to 3 decimal places. Now, I want to make it such that it has n decimal places. In effect, I want something like:
[NSString stringWithFormat:#"0%.%if", n, s];
//n is the precision argument, s is the float argument
But for obvious reasons, it does not work.
Is there a workaround?

You can use …"%.*f", n, s. For more information, stringWithFormat: follows the IEEE printf spec.
Not sure what the 0 prefix is for in your original format string. You certainly don't need it as part of the format specification. If it's for zero padding up to, say, two digits, you should do something like "%0*.*f", 3 + n, n, s.

You can pass a star (*) as the precision width in the format string. * star signifies that the width will be specified as a variable in the variable arguments (before the variable to be printed). So
[NSString stringWithFormat:#"0%.*f", n, s];
Where n is an integer describing the width, and s is the floating point value.

Related

How do I get doubleValue to return a decimal number more than six places?

When the following executes:
NSString *scratchString = #".123456789";
CGFloat scratchNum = [scratchString doubleValue];
scrathNum contains 0.123457
How can I get scratchNum to contain all of the digits? No matter what I try it rounds to 6 places.
CGFloat is a floating point number -- a float or a double (depending on which typedef is chosen by the compiler).
There's no concept of floating point numbers not "containing all of the digits". Their internal representation varies, but in this case your C float is represented by the IEEE 754 standard.
In this case, your "rounding" is a consequence of whatever is taking that floating point number and converting it from a binary form to a textual form. This could be the Xcode IDE itself (e.g. visualizing the value in the debugger), or maybe you're using a printf statement and have a specific formatting specified.

"unsigned int" prints as a negative number?

I am taking an integer, in this case 192, and left shifting it 24 spaces. The leading 1 is causing it to become negative, it seems.
unsigned int i = 192;
unsigned int newnumber = i << 24;
NSLog(#"newnumber is %d",newnumber);
I am expecting 3,221,225,472 but I get -1,073,741,824 (commas added for clarity)
An unsigned integer shouldn't be negative right?
Because you reinterpret it in NSLog as a signed integer. You should use %u to see an unsigned value.
There is no way for a function with variable number of arguments to know with certainty the type of the value that you pass. That is why NSLog relies on the format string to learn how many parameters you passed, and what their types are. If you pass a type that does not match the corresponding format specifier, NSLog will trust the specifier and interpret your data according to it. Modern compilers may even warn you about it.
You wan to do NSLog(#"newnumber is %u",newnumber);
%d converts it back to a signed int.
%d means "signed integer"; use %u for "unsigned integer".

Working with big numbers in Objective-C?

I need to convert values like 1393443048683555715 to HEX. But, first of all, i cann't display it as decimal using NSLog(), for example.
Ok, it works:
NSLog(#"%qu", 1393443048683555706);
But what about converting to HEX. What type i have to use to store this big value?
NSLog([NSString stringWithFormat: #"%x", 1393443048683555706]);
// result eb854b7a. It's incorrect result!
but i forgot to say that this big number represented as string #"1393443048683555706" (not int)
You can use %qi and %qu format specifiers with NSLog to display 64-bit integers. Your constant appears to fit in 64-bit signed number, with the limits of:
[−9223372036854775808 to 9223372036854775807]
The "x" format specifier is for 32-bit numbers; you need to use either "qx" or "qX" (depending on whether you want the letter values to be uppercase or not). These are the formatters for unsigned long long values, see:
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW1
Next, you should not pass a string as you have done above directly to NSLog - this can cause a crash.
NSLog(string); // bad!!
NSLog(#"%#", string); // good
So if your value comes as a string, you'll want to do this:
NSString *longNumber = #"1393443048683555706";
NSLog(#"%qx", [longNumber longLongValue]);
If the string value can't be coerced to a number, longLongValue will return 0. I'll leave it to you do handle the error (and bounds) checking - see NSString for details.
If you want to save the hex value as a string, do this:
NSString *hexRepresentation = [NSString stringWithFormat:#"%qx", [longNumber longLongValue]];
Again, best to take care for error handling.

Objective c: Parsing string to float, avoid extra decimals

Im converting some information Im receiving by a string to a float to get the sum of all of them.
The problem is when I convert the float, for example:
myString = #"13502.63"
float *f = [myString floatValue];
NSLog(#"Converted %f", f);
The result of "f" is 13502.629883
This thing is ok for some values, but when I have to add a big amount of this values, these extra decimals make the result incorrect.
Could anybody help me, please?
Thanks
If you want accuracy you should not use float. Use NSDecimalNumber.
NSString *myString = #"13502.63";
NSDecimalNumber *number = [NSDecimalNumber decimalNumberWithString:myString];
Unfortunately all floating point types in any language will have this problem, as they have to convert into an underlying binary integer format.
Have you considered using NSDecimalNumber?
These will be much slower than a float, but if that is not a problem, then they are much more accurate for such calculations.
If you need speed for some reason, would a double or long-double be accurate enough?
float numbers have no exact representation, that is the reason why "13502.63" is converted to 13502.629883; this is the closest float to the original number.
So, I don't think there is an easy solution with float. You should try NSDecimalNumber. I don't know about the performance, but it should give you an exact representation.

How to Turn Number into a String with Format?

Say I have a number, double, or NSNumber, 3.333333
I want that to turn that into #"3.3"
How would I do so?
Can I do NSString stringWithFormat? But what's the format?
NSString *str = [NSString stringWithFormat:#"%.1f", yourDouble];
or for NSNumber:
NSString *str = [NSString stringWithFormat:#"%.1f", [yourNSNumber doubleValue]];
0.0f means the amount of digits before and after the decimal. So #Wevah's answer would be correct, but keeping that in mind will save you time in the future.
%f stands for a float variable which I am sure you understand. What you would need to display this is a float variable because it contains a decimal. Like people have stated before, you will need to use %.1f
The % just tells the compiler that a special character is coming up.
The f tells the compiler that it is a float variable.
The .1 tells the compiler how many decimal places your float variable is to have. If you would want to have 6 decimal places, then you would us %.6f
Yes, you will want to use string with format.
Say you have a UILabel, then you will want to say
theLabel'sName.text = [NSString stringWithFormat:#"%.1f", ((float)int1 / int2)];
You need the (float) to tell the compiler that whatever int1 / int2 is, is a float variable.
If your NSNumber instance is called myNumber then do
[myNumber stringValue];