float format variable with integer value in string - iphone

I was facing with one minor issue, and I'm wondering: Why?
here we have some string:
[NSString stringWithFormat#"%.3f/%.3f/%.3f/%i", 1.0, 1.0, 1, 1];
in this case, result is 1.000/1.000/1/abra-kadabra like 34875689.
Why it's happens? Of course, I know, when we change the third value to 1.0, then everything will be okay.
So, please, explain me the deep proces of this operation.

Since you wrote %f, the compiler expects a float but recognizes an int. Writing 1 instead of 1.0 tells the compiler it's an integer constant instead of 1.0, which is a float constant.

Related

Printing CGFloat in Swift

I'm trying to get familiar with the Swift and test several things.
Here's a strange thing which I can't understand.
var count : NSInteger = 19
var percent : CGFloat = 22.01
var random : NSInteger = NSInteger(percent)
NSLog("%d, %f, %d", count, percent, random);
println("\(count), \(percent), \(random)")
It should print 19, 22.01, 22 but the log is...
19, 0.000000, 33875549
19, 22.0100002288818, 22
What's wrong here? After I removed the type specifier, it works fine with println not with NSLog.
Any Idea why the log is not correct?
ADDED
What about println? Using \() has no way to print 22.01?
My guess is you're compiling for 32-bit iOS, where CGFloat is a 32-bit float.
The closest float to 22.01 is exactly 22.0100002288818359375.
The closest 64-bit double to 22.01 is exactly 22.010000000000001563194018672220408916473388671875.
It appears that Swift string interpolation converts a double to the shortest string that would convert back to exactly the same double. It converts a float to a double (with the extra bits being zeros), then converts the double to a string as if it had been given a double in the first place.
The shortest string that converts back to Double(22.010000000000001563194018672220408916473388671875) is 22.01. But the shortest string that converts back to Double(22.0100002288818359375) is 22.0100002288818.
CGFloats are weird since they can be 32 or 64 bit depending on the system. It seems that NSLog has an issue with them. If you type percent explicitly as a Float or Double it will work correctly. You can also get the native type with cgfloat.native.
NSLog("%d, %f, %d", count, percent.native, random);
Use %# for CGFloat and it works fine:
NSLog("%d, %#, %d", count, percent, random);
This works because you can call .description on a CGFloat.

Swift: NSNumber is not a subtype of Float

I tried the code from Swift Programming Language in playground and got the following error "NSNumber is not a subtype of Float", I just modified it slightly by making x and y of type Float in struct Point. What am I missing?
If I added Float type to centerX and centerY, I got error: Could not find an overload for '/' that accepts the supplied arguments.
The error message is completely unrelated to the actual error... The actual error is cannot convert Double to Float.
In Size, x and y are Double (default type of float literal) but in Point, width and height are Float. They are different types and you can't mix them without explicit conversion.
There are number of ways to fix it. You can change them all to Double or Float.
e.g.
class Point
{
var x:Double
var y:Double
}
or you can convert them to correct type by doing Float(centerX)
ps: can you post the code next time so I can change it without retype them

Float only printing whole numbers?

Why is it that when I run this code in a loop, only whole numbers are printed in the console?
for (int i = 1; i <= 50; i++) {
zombieSpeed[i] = (((arc4random()%40)+2)/7);
NSLog(#"%f", zombieSpeed[i]);
}
The problem is here
zombieSpeed[i] = (((arc4random()%40)+2)/7);
instead of 40, 2, 7 you should use 40.0, 2.0, 7.0
Also make sure that ZombieSpeed is of float type
This line needs to use Float values (40.0, 2.0, 7.0)
zombieSpeed[i] = (((arc4random()%40)+2)/7);
The division is an integer division, use explicit decimal point as 40.0 or typecast, so that at least one operand is floating point, which upcasts the entire expression to be evaluated as floating point. Make sure that any left hand side variable to which you assign the computer value is of floating point type with equal or greater width (to preserve the precision).

How to safely create an NSInteger from an CGFloat?

I've got an CGFloat but need it as an NSInteger. The float value is like 2.0f, so I don't mind about fractional parts and loosing precision. What's a legal way to convert it into NSInteger without trouble (except the loss of precision, of course)?
NSInteger niceInt = niceCGFloat;
seems too simple, smells buggy. Maybe you can explain?
You want the c function lrintf() which rounds a floating point to a long int.
There's always the risk that 2.0f may actually be 1.9999999999f when represented in binary. Your conversion to int would then lead to 1 instead of 2.
To avoid this, I would add 0.5f to your float value. This would also have the effect of rounding your float, instead of truncating it.
NSInteger niceInt = niceCGFloat + 0.5f;

Secure and valid way for converting a "float integer" into a natural integer?

I have a CGFloat that contains only "integers", in the meaning that it actually wants to represent integers only but due to float inprecision it may happen that it internally has a 23.00000000000000000000000142 or something like that. I try to feed an NSDecimalNumber with clean input, so I need to make sure this is truly a naked integer with no dirt. Well, I think this is a good way, but maybe I am wrong:
NSInteger *intVal = floatVal;
That would just get rid of those fragmental parts at the end of the tale, right? Or is there a more secure way to convert it into a true integer?
If you just want to take the integer part of a float then I believe you can just do the following:
CGFloat myfloat = 23.0000000000142f;
int myInt = (int) myfloat;