If the arguments of a method call for floats to be passed, can one simply pass 10 as opposed to 10.0? I have been doing this, but often see code which specify .0 and have been wondering if there are any reasons to do so. Thank you.
It's not necessary, but it's a good idea to use the correct type and/or add explicit casts when you do this - more for self-documentation purposes than anything else. For literal values just specify the constant as e.g. 10.0f - for variables just use a C-style typecast, e.g. (float)i.
The compiler will generally coerce numbers to the correct type, but it doesn't hurt to be explicit to promote readability.
The constant value 10.0 is actually a double to most C and C++ compilers, whereas 10.0f is a single-precision floating point number. If you're passing a variable to a function and you know the passed type is wrong, cast it using C notation (float)i or C++ notation float(i) depending on your compiler.
Related
I am a beginner in Kotlin.
I'm most familiar with Python, and I just read through the basic Java Tutorial https://docs.oracle.com/javase/tutorial/java/index.html before jumping into Kotlin.
A question came up in my mind while reading this section of the documentation of Kotlin
https://kotlinlang.org/docs/reference/basic-types.html#explicit-conversions
What I have understood from above section of the documentation is:
For assignments =, implicit type conversion happens. If the lefthand side's type is a supertype or same type of righthand side's type the code would compile. Otherwise it's a compile error. In case of Int and Long, they are both subtypes of Number but neither of them subtypes of each other, so the implicit conversion would not work. Therefore we need to use methods like .toLong() or .toInt() to explicitly convert them.
Then when I read the part
val l = 1L + 3 // Long + Int => Long
I started wondering if implicit type conversion would be taking place in this situation.
The documentation says this has to do with the operator overloading.
How is this operator overloading implemented under the hood?
I tried to find the source code at Github https://github.com/JetBrains/kotlin/blob/master/core/builtins/native/kotlin/Primitives.kt ,
but here the functions are only declared but not implemented. Where can I find the implementations?
It seems that operation overloading does not actually perform type conversion. Do we just implementing all possible functions with same name but different parameter type signatures, so that the type is inferred, then the function with the matching signature is selected?
And the general question: In Kotlin, exactly at which situations does implicit conversion happen?
For assignments =, implicit type conversion happens. If the lefthand side's type is a supertype or same type of righthand side's type the code would compile.
Assignments aren't special in this. More generally, if the expected type of an expression is a supertype or the same as actual type, the code compiles; it's just that the expected type for the right-hand side of an assignment is the left-hand side's type. I wouldn't say there is an implicit conversion inserted, but I don't think anything breaks if you see it that way.
Do we just implementing all possible functions with same name but different parameter type signatures, so that the type is inferred, then the function with the matching signature is selected?
Yes, exactly (for this case). If you want to support primitive types, you need to provide overloads for all of them.
So 1L + 3 is just a method call so far as the parsing and type-checking is concerned (`Long.plus(Int): Long specifically), no implicit conversion is involved. But these methods are built into the compiler to handle specially which is why you don't see an implementation.
It becomes two bytecode instructions i2l ("convert an int into a long") and ladd ("add two longs"), but that's not something you should probably care about yet, or for a long time.
And the general question: In Kotlin, exactly at which situations does implicit conversion happen?
Smart casts are the closest Kotlin has to implicit conversions but they are sufficiently different from i.c.s in other languages that I wouldn't use the name. So I'd say never.
I understand from earlier questions that whitespace is irrelevant in pointer declarations in Objective-C, e.g:
float* powerPtr;
float * powerPtr;
float *powerPtr;
do mean exactly the same (apart from stylistic considerations...) but is
(float *)powerPtr;
(with parentheses) the same too? Don't these parentheses implicitly "mean" that the asterisk should be in some way related to float, when it should be instead more logically related to powerPtr? (The actual pointer is actually powerPtr, not float, if I am right)
Your code:
(float *)powerPtr;
is not a valid declaration in (Objective-)C.
This is an expression which casts the value in the variable powerPtr to be of type float *.
The result of that cast is just discarded as it is not used, your compiler might give a warning - Xcode 8 issues an "Expression result unused".
Addendum
From your comment the syntax you show was meant to be part of a method declaration, e.g. something like:
- (void)doSomething:(float *)powerPtr;
that would occur in an #interface. The parentheses here are not being used for grouping per se but to delimit the type. As to you concern:
Don't these parentheses implicitly "mean" that the asterisk should be in some way related to float, when it should be instead more logically related to powerPtr?
The * is part of the type, float * is the type specification for "pointer to float". The identifier powerPtr is associated with the whole type specification.
HTH
This seems like it should be really simple but I'm having trouble finding the answer online.
What's the proper way to define a Decimal variable and initialize it with constant value in C++/CLI?
In C# it would be:
decimal d = 1.1M;
In C++/CLI I've been doing:
Decimal d = (Decimal)1.1;
Which works for some numbers, but I suspect it's just converting from double.
I notice there's a constructor: Decimal(int, int, int, bool, unsigned char) but was hoping there's an easier way to deal with large specific numbers.
You are indeed casting the number. You can, as mentioned, parse from a string or divide integers, or you may want to use the BigRational data type. Independently of the option you choose you may create a utility method in a static class to do it so you don't have to repeat it all the time.
You can also suggest on the VS UserVoice Site to allow number sufixes like in C#.
Is there any advantage to using a constant (unchangable) than just not changing a variable?
Depending on your language and compiler, a constant may get inlined & optimized when built. Variables will likely eat up stack space even if it never changes.
By making the value constant, the compiler can just substitute it. If you have x / 2, for example, the compiler can compute the value and use that instead of having to emit code to retrieve the value of x and then divide it by 2.
Also, you don't have to worry about accidentally changing the value. For example, in C-like languages you might accidentally type if (x = 2) when you meant if (x == 2) which will change the value of x if it's a variable.
Anyone maintaining your code in the future (including you) won't have to look around to see where (if anywhere) a constant is changed when finding a bug or adding a feature - they'll know right off the bat that it can't be changed.
In some program languages, declaring something to be constant will allow a compiler to make optimizations which would not otherwise be possible. Further, declaring something to be constant can be a useful way of documenting that there are places in the code which might be broken should the value change.
Unfortunately, some programming languages sometimes do evil things with things that are declared constant. For example, in some .net languages, if a value type which is declared read-only is passed by modifiable reference, the compiler will, rather than refusing to allow such an action, instead make a copy and pass that. Such implicit copying will impair efficiency, and may result in unexpected semantics.
Are there any other ways of changing a variable's type in a statically typed language like Java and C++, except 'casting'?
I'm trying to figure out what the main difference is in practical terms between dynamic and static typing and keep finding very academic definitions. I'm wondering what it means in terms of what my code looks like.
Make sure you don't get static vs. dynamic typing confused with strong vs. weak typing.
Static typing: Each variable, method parameter, return type etc. has a type known at compile time, either declared or inferred.
Dynamic typing: types are ignored/don't exist at compile time
Strong typing: each object at runtime has a specific type, and you can only perform those operations on it that are defined for that type.
Weak typing: runtime objects either don't have an explicit type, or the system attempts to automatically convert types wherever necessary.
These two opposites can be combined freely:
Java is statically and strongly typed
C is statically and weakly typed (pointer arithmetics!)
Ruby is dynamically and strongly typed
JavaScript is dynamically and weakly typed
Genrally, static typing means that a lot of errors are caught by the compiler which are runtime errors in a dynamically typed language - but it also means that you spend a lot of time worrying about types, in many cases unnecessarily (see interfaces vs. duck typing).
Strong typing means that any conversion between types must be explicit, either through a cast or through the use of conversion methods (e.g. parsing a string into an integer). This means more typing work, but has the advantage of keeping you in control of things, whereas weak typing often results in confusion when the system does some obscure implicit conversion that leaves you with a completely wrong variable value that causes havoc ten method calls down the line.
In C++/Java you can't change the type of a variable.
Static typing: A variable has one type assigned at compile type and that does not change.
Dynamic typing: A variable's type can change while runtime, e.g. in JavaScript:
js> x="5" <-- String
5
js> x=x*5 <-- Int
25
The main difference is that in dynamically typed languages you don't know until you go to use a method at runtime whether that method exists. In statically typed languages the check is made at compile time and the compilation fails if the method doesn't exist.
I'm wondering what it means in terms of what my code looks like.
The type system does not necessarily have any impact on what code looks like, e.g. languages with static typing, type inference and implicit conversion (like Scala for instance) look a lot like dynamically typed languages. See also: What To Know Before Debating Type Systems.
You don't need explicit casting. In many cases implicit casting works.
For example:
int i = 42;
float f = i; // f ~= 42.0
int b = f; // i == 42
class Base {
};
class Subclass : public Base {
};
Subclass *subclass = new Subclass();
Base *base = subclass; // Legal
Subclass *s = dynamic_cast<Subclass *>(base); // == subclass. Performs type checking. If base isn't a Subclass, NULL is returned instead. (This is type-safe explicit casting.)
You cannot, however, change the type of a variable. You can use unions in C++, though, to achieve some sort of dynamic typing.
Lets look at Java for he staitically typed language and JavaScript for the dynamc. In Java, for objects, the variable is a reference to an object. The object has a runtime type and the reference has a type. The type of the reference must be the type of the runtime object or one of its ancestors. This is how polymorphism works. You have to cast to go up the hierarchy of the reference type, but not down. The compiler ensures that these conditions are met. In a language like JavaScript, your variable is just that, a variable. You can have it point to whatever object you want, and you don't know the type of it until you check.
For conversions, though, there are lots of methods like toInteger and toFloat in Java to do a conversion and generate an object of a new type with the same relative value. In JavaScript there are also conversion methods, but they generate new objects too.
Your code should actally not look very much different, regardless if you are using a staticly typed language or not. Just because you can change the data type of a variable in a dynamically typed language, doesn't mean that it is a good idea to do so.
In VBScript, for example, hungarian notation is often used to specify the preferred data type of a variable. That way you can easily spot if the code is mixing types. (This was not the original use of hungarian notation, but it's pretty useful.)
By keeping to the same data type, you avoid situations where it's hard to tell what the code actually does, and situations where the code simply doesn't work properly. For example:
Dim id
id = Request.QueryString("id") ' this variable is now a string
If id = "42" Then
id = 142 ' sometimes turned into a number
End If
If id > 100 Then ' will not work properly for strings
Using hungarian notation you can spot code that is mixing types, like:
lngId = Request.QueryString("id") ' putting a string in a numeric variable
strId = 42 ' putting a number in a string variable