Why do you need to append an L or F after a value assigned to a C++ constant?
Floating-point constants have type double
by default in C++. Since a long double
is more precise than a double
, you may lose significant digits when long double
constants are converted to double
. To handle these constants, you need to use the L
suffix to maintain long double
precision. For example,
long double x = 8.99999999999999999;
long double y = 8.99999999999999999L;
std::cout.precision(100);
std::cout << "x=" << x << "\n";
std::cout << "y=" << y << "\n";
The output for this code on my system, where double
is 64 bits and long double
96, is
x=9
y=8.9999999999999999895916591441391574335284531116485595703125
What's happening here is that x
gets rounded before the assignment, because the constant is implicitly converted to a double
, and 8.99999999999999999
is not representable as a 64-bit floating point number. (Note that the representation as a long double
is not fully precise either. All of the digits after the first string of 9
s are an attempt to approximate the decimal number 8.99999999999999999
as closely as possible using 96 binary bits.)
In your example, there is no need for the L
constant, because 3.0
is representable precisely as either a double
or a long double
. The double
constant value is implicitly converted to a long double
without any loss of precision.
The case with F
is not so obvious. It can help with overloading, as Zan Lynx points out. I'm not sure, but it may also avoid some subtle rounding errors (i.e., it's possible that encoding as a float
will give a different result from encoding as a double
then rounding to a float
).
f after number
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.
what is the reason for explicitly declaring L or UL for long values
When a suffix L
or UL
is not used, the compiler uses the first type that can contain the constant from a list (see details in C99 standard, clause 6.4.4:5. For a decimal constant, the list is int
, long int
, long long int
).
As a consequence, most of the times, it is not necessary to use the suffix. It does not change the meaning of the program. It does not change the meaning of your example initialization of x
for most architectures, although it would if you had chosen a number that could not be represented as a long long
. See also codebauer's answer for an example where the U
part of the suffix is necessary.
There are a couple of circumstances when the programmer may want to set the type of the constant explicitly. One example is when using a variadic function:
printf("%lld", 1LL); // correct, because 1LL has type long long
printf("%lld", 1); // undefined behavior, because 1 has type int
A common reason to use a suffix is ensuring that the result of a computation doesn't overflow. Two examples are:
long x = 10000L * 4096L;
unsigned long long y = 1ULL << 36;
In both examples, without suffixes, the constants would have type int
and the computation would be made as int
. In each example this incurs a risk of overflow. Using the suffixes means that the computation will be done in a larger type instead, which has sufficient range for the result.
As Lightness Races in Orbit puts it, the litteral's suffix comes before the assignment. In the two examples above, simply declaring x
as long
and y
as unsigned long long
is not enough to prevent the overflow in the computation of the expressions assigned to them.
Another example is the comparison x < 12U
where variable x
has type int
. Without the U
suffix, the compiler types the constant 12
as an int
, and the comparison is therefore a comparison of signed ints.
int x = -3;
printf("%d\n", x < 12); // prints 1 because it's true that -3 < 12
With the U
suffix, the comparison becomes a comparison of unsigned ints. “Usual arithmetic conversions” mean that -3 is converted to a large unsigned int:
printf("%d\n", x < 12U); // prints 0 because (unsigned int)-3 is large
In fact, the type of a constant may even change the result of an arithmetic computation, again because of the way “usual arithmetic conversions” work.
Note that, for decimal constants, the list of types suggested by C99 does not contain unsigned long long
. In C90, the list ended with the largest standardized unsigned integer type at the time (which was unsigned long
). A consequence was that the meaning of some programs was changed by adding the standard type long long
to C99: the same constant that was typed as unsigned long
in C90 could now be typed as a signed long long
instead. I believe this is the reason why in C99, it was decided not to have unsigned long long
in the list of types for decimal constants.
See this and this blog posts for an example.
Why does scanf() need %lf for doubles, when printf() is okay with just %f?
Because C will promote floats to doubles for functions that take variable arguments. Pointers aren't promoted to anything, so you should be using %lf
, %lg
or %le
(or %la
in C99) to read in doubles.
Assigning a value to long and float primitive types in Java
Numeric constants without any postfix have default types. If they are integer (i.e. they have no floating point), the default type is int
. If they have a floating point, the default type is double
.
Therefore an integer constant without the L suffix (which denotes a long
literal) can't be larger than Integer.MAX_VALUE
, and the double
constant 10.1
can't be assigned to a float
variable without an explicit cast.
On the other hand, the int
10
can be assigned to a float
variable, as well as the float
10.1f
.
Append an object to a list in R in amortized constant time, O(1)?
If it's a list of string, just use the c()
function :
R> LL <- list(a="tom", b="dick")
R> c(LL, c="harry")
$a
[1] "tom"
$b
[1] "dick"
$c
[1] "harry"
R> class(LL)
[1] "list"
R>
That works on vectors too, so do I get the bonus points?
Edit (2015-Feb-01): This post is coming up on its fifth birthday. Some kind readers keep repeating any shortcomings with it, so by all means also see some of the comments below. One suggestion for list
types:
newlist <- list(oldlist, list(someobj))
In general, R types can make it hard to have one and just one idiom for all types and uses.
Why is the letter f used at the end of a float no.?
The f
indicates it's a floating point literal, not a double literal (which it would implicitly be otherwise.) It hasn't got a particular technical name that I know of - I tend to call it the "letter suffix" if I need to refer to it specifically, though that's somewhat arbitrary!
For instance:
float f = 3.14f; //Compiles
float f = 3.14; //Doesn't compile, because you're trying to put a double literal in a float without a cast.
You could of course do:
float f = (float)3.14;
...which accomplishes near enough the same thing, but the F is a neater, more concise way of showing it.
Why was double chosen as the default rather than float? Well, these days the memory requirements of a double over a float aren't an issue in 99% of cases, and the extra accuracy they provide is beneficial in a lot of cases - so you could argue that's the sensible default.
Note that you can explicitly show a decimal literal as a double by putting a d
at the end also:
double d = 3.14d;
...but because it's a double value anyway, this has no effect. Some people might argue for it advocating it's clearer what literal type you mean, but personally I think it just clutters code (unless perhaps you have a lot of float literals hanging around and you want to emphasise that this literal is indeed meant to be a double, and the omission of the f isn't just a bug.)
Why can a function modify some arguments as perceived by the caller, but not others?
Some answers contain the word "copy" in the context of a function call. I find it confusing.
Python doesn't copy objects you pass during a function call ever.
Function parameters are names. When you call a function, Python binds these parameters to whatever objects you pass (via names in a caller scope).
Objects can be mutable (like lists) or immutable (like integers and strings in Python). A mutable object you can change. You can't change a name, you just can bind it to another object.
Your example is not about scopes or namespaces, it is about naming and binding and mutability of an object in Python.
def f(n, x): # these `n`, `x` have nothing to do with `n` and `x` from main()
n = 2 # put `n` label on `2` balloon
x.append(4) # call `append` method of whatever object `x` is referring to.
print('In f():', n, x)
x = [] # put `x` label on `[]` ballon
# x = [] has no effect on the original list that is passed into the function
Here are nice pictures on the difference between variables in other languages and names in Python.
Referencing a char* that went out of scope
Inside the scope where b
is defined, it is assigned the address of a string literal. These literals typically live in a read-only section of memory as opposed to the stack.
When you do a=b
you assign the value of b
to a
, i.e. a
now contains the address of a string literal. This address is still valid after b
goes out of scope.
If you had taken the address of b
and then attempted to dereference that address, then you would invoke undefined behavior.
So your code is valid and does not invoke undefined behavior, but the following does:
int *a = NULL;
{
int b = 6;
a = &b;
}
printf("b=%d\n", *a);
Another, more subtle example:
char *a = NULL;
{
char b[] = "stackoverflow";
a = b;
}
printf(a);
The difference between this example and yours is that b
, which is an array, decays to a pointer to the first element when assigned to a
. So in this case a
contains the address of a local variable which then goes out of scope.
EDIT:
As a side note, it's bad practice to pass a variable as the first argument of printf
, as that can lead to a format string vulnerability. Better to use a string constant as follows:
printf("%s", a);
Or more simply:
puts(a);
Related Topics
Under What Circumstances Is It Advantageous to Give an Implementation of a Pure Virtual Function
Why Do My Sfinae Expressions No Longer Work with Gcc 8.2
What Does ## in a #Define Mean
C++ Back End Call the Python Level Defined Callbacks with Swig Wrapper
Are End+1 Iterators for Std::String Allowed
C++ Connect Output Stream to Input Stream
Casting to Void* and Back to Original_Data_Type*
Move the String Out of a Std::Ostringstream
Why Is the Address of This Volatile Variable Always at 1
After Sending a Lot, My Send() Call Causes My Program to Stall Completely. How Is This Possible
Use Static_Assert to Check Types Passed to MACro
Error C2228: Left of '.Size' Must Have Class/Struct/Union
Test Whether a Class Is Polymorphic
Cmake Error: "Add_Subdirectory Not Given a Binary Directory"