Edit: I am looking for reinterpret_castin Objective-C so the following is meaningless for my intended question.
Are there static casts in Objective-C?
e.g. in this C++ example static_cast is used for a good reason:
float rnd = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
I can think of using a union or pointers to directly access the
integer value as a float but that would make the code much more
complex.
How would I do the same thing as in the C++ example conveniently in
Objective-C?
Objective C is a superset of C so do this the C way and simple casts
float rnd = (float) (rand()) / (float)(RAND_MAX);
After the clarification you are after reinterpret_cast:
You are correct you can do it with a union. If you want to do it inline you can use a cast, address-of and indirection...
The C-style cast (type)expr in both (Objective-)C and C++ works similarly: if the equivalent of a static_cast is appropriate it does that, e.g. between int and float and other value types; otherwise it will do the equivalent of a reinterpret_cast, e.g. between pointer-types.
So you just need to convert to a pointer, cast, and indirect. E.g.:
int z = 0xDEADBEEF;
float y = *(float *)&z;
NSLog(#"%d -> %f", z, y);
Yes it's a bit ugly, but then what you are doing is as well ;-) To make it a bit nicer define it as a macro:
#define REINTERPRET(type, expr) (*(type *)&(expr))
which you can use as:
int z = 0xDEADBEEF;
float y = REINTERPRET(float, z);
NSLog(#"%d -> %f", z, y);
As with reinterpret_cast, you should use this sparingly and with care!
HTH
Related
How would I translate this Obj-C into Swift? I'm not sure about the new Swift 2 syntax and all.
unsigned char pixel[4] = {0};
According to the comments there seems to be an additional question about what the Objective-C code means: unsigned char pixel[4] declares pixel as an array of 4 unsigned char's. The = {0} initializes all elements of the array to 0.
Hence the simplest conceptual equivalent in Swift is:
var pixel: [UInt8] = [0,0,0,0]
Unlike C and Objective-C, Swift does not allow specifying the size of the array in advance and thus all four zeroes must be given to obtain the correct length - in C and Objective-C the extra zeroes can be omitted for brevity since it is already known that the array's size is 4.
Arguably you could use CUnsignedChar instead of UInt8 (as the unsigned char in C is not strictly guaranteed to be UInt8), but it is unnecessary unless you're going to be passing the values to a C function expecting unsigned char. In any case they are extremely likely to be the same type, and on the odd platforms where they aren't the same type it is more likely that the C code is actually wrong and used unsigned char where they meant uint8_t.
You can do it this way :
var pixel = [UInt8](count:4, repeatedValue:0)
Or :
var pixel:[UInt8] = [0,0,0,0]
Swift equivalent of unsigned char is CUnsignedChar
var pixel : [CUnsignedChar]()
You cannot give fixed length arrays in CMutablePointers in swift. So you have to declare like this. Reference
See this link to overcome this issue
Testing out some third party objective-C code I see the following:
int beepData[] = {1200,100};
What am I looking at here? An int is being created from a pair of other integers? I've not seen this feature before.
I would also like to know how to create the same variable in Swift.
EDIT
I assumed this was returning an int, not an array. The code I'm reviewing looks like this:
int beepData[] = {1200,100};
[[DTDevices sharedDevice] barcodeSetScanBeep:TRUE volume:10 beepData:beepData length:sizeof(beepData) error:nil];
Where the method signature I am intending to pass the variable to is:
-(BOOL)barcodeSetScanBeep:(BOOL)enabled volume:(int)volume beepData:(int *)data length:(int)length error:(NSError **)error;
I guess the right question might have been - what is (int *) and how might I create one in Swift?
What am I looking at here?
That is an array of ints, with two elements.
[How can I] create the same variable in Swift?
The same variable in swift might be declared as:
var beepData : [Int] = [ 1200, 100 ]
You might find this answer about different ways to declare an array in C useful
What is (int *)
It's an int pointer, it points to the memory address of an int. Incrementing it would move along the memory addresses (in int-sized chunks) and point to the next bit of memory.
[1][3][5][4][2]
^
This little arrow represents an int*. Even though it currently points to 1,
incrementing it doesn't equal 2. In this case it would equal 3, the value of the int in the next block of memory.
[1][3][5][4][2]
^
How might I create one in Swift?
To be quite honest, I'm not sure if Swift has pointers in the normal sense. I've not used it a great deal. However, if you are porting that method, I'd probably give it an array of ints.
func barcodeSetScanBeep(enabled : Bool, volume : Int, beepData: [Int], length : Int, error : NSError)
That's a C array, declared with 1200 and 100 as the members of the array.
Its declared with the type, and a bracket with the size (or empty for compiler deduced size), such as int cArrayOfInts[] = blahblahblah.
Note how the members of the array can be primitives, instead of objects. This isn't possible in Objective-C.
To recreate this in swift, simply use var beepData = [1200, 100] and it will be type inferred to an array of Ints.
James already answered the particulars of your question - consider this some additional information.
Declarations in C are based on the types of expressions, not objects. If you have an array of integers and you want to access the i'th integer, you would write
x = arr[i];
The type of the expression arr[i] is int, so the declaration of arr is written as
int arr[N]; // arr is an N-element array of int
Similar logic applies to pointer declarations; if you have a pointer to a double and you want to access the pointed-to value, you'd write
y = *p;
The type of the expression *p is double, so the declaration of p is written as
double *p;
Same for function declarations; you call a function that returns an integer as
x = f();
The type of the expression f() is int, so the declaration of the function is written as
int f( void ); // void means the function takes no parameters
C declaration syntax uses something called a declarator to specify an object's array-ness, pointer-ness, or function-ness. For example:
int x, arr[10], *p, f(void);
declares x as a plain int, arr as a 10-element array of int, p as a pointer to an int, and f as function taking no parameters and returning int.
You'll occasionally see pointer declarations written as T* p, however they will be parsed as T (*p); the * is always part of the declarator, not the type specifier.
C declaration syntax allows you to create some pretty complex types in a compact format, such as
int *(*(*f[N])(void))[M];
In this declaration, f is an N-element array of pointers to functions returning pointers to M-element arrays of pointers to int.
In your declaration
int beepData[] = {1200, 100};
beepData is being declared as an array of an unknown size; the size is taken from the number of elements in the initializer {1200, 100}, in this case 2.
I know nothing about Swift, so I wouldn't know how to translate the C code to it. The best I can do is explain how the C code works.
With the Objective-C's #property directive I can declare properties for which getter and setter methods will be created automatically. I can't think of any particular reason to use instance variables where I would have to write my own setter and getters, but I'm sure there must be an example where using instance variables is more preferable. Could there be any reason to use instance variables instead of properties? Are there any practical examples for it?
The problem is on this line
slope = (line_cordinates[3] - line_cordinates[1]) / (line_cordinates[2] - line_cordinates[0]);
slope is declared a float, but line_cordinates is an array of int.
So you are doing all of the math on the right hand side as int math, then assigning it to a float. So the final result of all the int operations is implicitly converted to float, but by then you have already lost the precision from truncation, etc.
The quickest fix would be to simply declare
float line_cordinates[4] = {0.0, 0.0, 0.0, 0.0};
Use,
slope = static_cast<float>((line_cordinates[3] - line_cordinates[1])) / (line_cordinates[2] - line_cordinates[0]);
You need to typecast any of the operand on right hand side to float. So expression will result in float.
int op int = int
float op int = float
I am doing a simple :
float x = 151.185436;
printf("x=%f",x);
and the result is
x=151.185440
Whats wrong here? I want to retain and print my original value of 151.185436
Thanks
Amarsh
floats just aren't very accurate. Try double. And read this: http://docs.sun.com/source/806-3568/ncg_goldberg.html
A float can only hold 32 bits (4 bytes) of information about your number - it can't just store as many decimal places as you need it to. 151.18544 is as close to your value that the float could represent without running out of bits.
For the precision you want, you need to use a double instead of a float.
Floats are inaccurate, use doubles. Also as you're using Objective C and not straight C it might be better if you use Objective C functions for this:
myNumber = [NSNumber numberWithDouble:151.185436];
NSLog(#"myNumber = %#", myNumber);
What does the f after the numbers indicate? Is this from C or Objective-C? Is there any difference in not adding this to a constant number?
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);
Can you explain why I wouldn't just write:
CGRect frame = CGRectMake(0, 0, 320, 50);
CGRect frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);
uses float constants. (The constant 0.0 usually declares a double in Objective-C; putting an f on the end - 0.0f - declares the constant as a (32-bit) float.)
CGRect frame = CGRectMake(0, 0, 320, 50);
uses ints which will be automatically converted to floats.
In this case, there's no (practical) difference between the two.
When in doubt check the assembler output. For instance write a small, minimal snippet ie like this
#import <Cocoa/Cocoa.h>
void test() {
CGRect r = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);
NSLog(#"%f", r.size.width);
}
Then compile it to assembler with the -S option.
gcc -S test.m
Save the assembler output in the test.s file and remove .0f from the constants and repeat the compile command. Then do a diff of the new test.s and previous one. Think that should show if there are any real differences. I think too many have a vision of what they think the compiler does, but at the end of the day one should know how to verify any theories.
Sometimes there is a difference.
float f = 0.3; /* OK, throw away bits to convert 0.3 from double to float */
assert ( f == 0.3 ); /* not OK, f is converted from float to double
and the value of 0.3 depends on how many bits you use to represent it. */
assert ( f == 0.3f ); /* OK, comparing two floats, although == is finicky. */
It tells the computer that this is a floating point number (I assume you are talking about c/c++ here). If there is no f after the number, it is considered a double or an integer (depending on if there is a decimal or not).
3.0f -> float
3.0 -> double
3 -> integer
The f that you are talking about is probably meant to tell the compiler that it's working with a float. When you omit the f, it is usually translated to a double.
Both are floating point numbers, but a float uses less bits (thus smaller and less precise) than a double.
A floating point literal in your source code is parsed as a double. Assigning it to a variable that is of type float will lose precision. A lot of precision, you're throwing away 7 significant digits. The "f" postfix let's you tell the compiler: "I know what I'm doing, this is intentional. Don't bug me about it".
The odds of producing a bug isn't that small btw. Many a program has keeled over on an ill-conceived floating point comparison or assuming that 0.1 is exactly representable.
It's a C thing - floating point literals are double precision (double) by default. Adding an f suffix makes them single precision (float).
You can use ints to specify the values here and in this case it will make no difference, but using the correct type is a good habit to get into - consistency is a good thing in general, and if you need to change these values later you'll know at first glance what type they are.
From C. It means float literal constant. You can omit both "f" and ".0" and use ints in your example because of implicit conversion of ints to floats.
It is almost certainly from C and reflects the desire to use a 'float' rather than a 'double' type. It is similar to suffixes such as L on numbers to indicate they are long integers. You can just use integers and the compiler will auto convert as appropriate (for this specific scenario).
It usually tells the compiler that the value is a float, i.e. a floating point integer. This means that it can store integers, decimal values and exponentials, e.g. 1, 0.4 or 1.2e+22.