Hi
you can say me what is ul in the expresion
# define F_CPU 1200000ul
where is the documentation, i look in the doc avr-lib-user, but i didn`t find anything.
thanks .
Hi
you can say me what is ul in the expresion
# define F_CPU 1200000ul
where is the documentation, i look in the doc avr-lib-user, but i didn`t find anything.
thanks .
UL = unsigned long
This isn't an avr-gcc or avr-libc specific thing, but part of the C language.
So, in effect it's a shortened form of:
#define F_CPU ((unsigned long)1200000)
You generally use it on integer constants outside 'int' range (which on an AVR is -32768..+32767) to ensure they are used in the way you intended.
hey! what is the exact means of unsigned Long(UL)
hey! what is the exact means of unsigned Long(UL)
hey! what is the exact means of unsigned Long(UL)
Btw., in terms of
#define F_CPU 1E6
instead, so you don't have to count the amount of zeros. As a
basic requirement for these macros is that you have to enable
compiler optimizations, all the floating-point math will be
eliminated by the cmopiler (but there is floating-point math
anyway, regardless of whether you declare it as 1000000, as
1000000ul, or as 1E6).
The ul suffix is mostly useless in the F_CPU define anyway, as a
numeric constant that does not fit into the range of `int' is
automatically extended to the next larger type, and the library
macros that process the F_CPU define also ensure the value is
always treated as an unsigned one internally.
The relevant paragraph in C99 is 6.4.4.1#5.
The intriguing thing in this is, that decimal constants are treated in a different way than the hexadecimal/octal.
---
I personally wouldn't go for the float notation (1E6) if the intention is to have an integer constant, even if it means to "spare" a few digits; I admit my reason for this is superstition rather than rational... :-)
JW
> The intriguing thing in this is, that decimal constants are
> treated in a different way than the hexadecimal/octal.
But only in that they could also take a signed type, while hex/oct constants
can only take an unsigned type.
But, in terms of F_CPU consumers, they have to ensure to always treat it as
an unsigned type before processing anyway.
> I personally wouldn't go for the float notation (1E6) if the
> intention is to have an integer constant, ...
Well, the CPU frequency is naturally a floating-point value. ;-)
It could easily enough take a value like 999.9996 kHz ...
I already wrote it a number of times: if your crystal is labelled
"1.8432 MHz", why would you bother counting how many zeros to add
to eventually turn this into an integer number, when you could
easily write it as "1.8432E6"?
(Alas, the author of
writing his tool, so anyone who also wants to use setbaud has to
bite into the sour grapes, and count how many zeros to add ...)
Thanks for this enlightening bit of information! This is one of those subtle things that most of us totally miss.
I wish there is a "flag" to highlight individual threads so they don't get lost in the ever-expanding thread list.
Jim
I wish there is a "flag" to highlight individual threads so they don't get lost in the ever-expanding thread list.
(Welcome to the World Wide Web :wink:)
If it is "for everyone" then we'd need some kind of vote-count mechanism, e.g. like the one at stackoverflow.com .
Hi,
Just out of curiousity..
say in a code if this UL is used in small constant numbers what should be the purpose ?
ex : #define ABCD 512ul
I have seen this with 64ul and 256ul too.
And that code was written by a really experianced person..
Any reason behind this ?
Thanks much
The same reason that it is used with larger numbers: to ensure calculations done with it are longs and not ints.
I have seen this with 64ul and 256ul too.
Thanks much for the reply's..
I'd like to add a brief note to this discussion... Often you'll see "L" used instead of "l", because in many fonts, lower-case el "l" is difficult to distinguish from number one "1". This is less of a problem if you use "ul", as the "u" helps separate the numeric part from the type specifier, but as a matter of convention, I always use "U", "L" or "UL" rather than "u", "l", or "ul".
A good programmer font helps reduce the need, but most code is write-once, read-many, so it is better to spend the extra effort to make it more readable for as wide an audience as makes sense.
Hi clawson
as per the rule of the compiler the value gets upgraded to its longer version if it does not fit into the current value.
So here 12000000 instead of fact is more than the 'int' type will be upgraded to the unsigned long type automatically even if you do not mention it as unsigned long using the literal.
if you can provide some more facts supporting your point than it would be appreciable.
correct me if I am wrong.
Reagrds
Hi clawson
as per the rule of the compiler the value gets upgraded to its longer version if it does not fit into the current value.
So here 12000000 instead of fact is more than the 'int' type will be upgraded to the unsigned long type automatically even if you do not mention it as unsigned long using the literal.
if you can provide some more facts supporting your point than it would be appreciable.
correct me if I am wrong.
Reagrds
Well, first note that the thread you responded to is nearly three years old.
Next, note that clawson said " to ensure they are used in the way you intended." Nothing wrong with that assertion that I can see.
I'm not a great standards interpreter, but if you are being pedantic are you sure that the type of 12 million without a suffix is not "long int" vs. "unsigned long int"?
Yes. 12000000 would be a signed long int.
You need the UL suffix to tell the compiler to treat the value as an unsigned long int
In practice most expressions that use F_CPU are unlikely to notice the difference.
You always need to check that intermediate expressions do not overflow or underflow.
David.
Hey Buddy
First of all let me clear one thing to you and rest of the guys of this forum that I am not a pedantic sort of guy.
Ok now about my question and your reply.
you said that this post is three years old, well my friend that's true and what you think I would not have seen this before posting.
Actually I was studying this type of typo used in C and let me tell you that still I am not able to digest few of facts regarding the suffixes provided in the C.
Here in this case you are right.
But what about this case:
unsigned long x= 150000UL;
what is the need felt by the programmer here to point or to typecast the integer constant while the space to be allocated has already been defined I mean as unsigned long.
Reagrds
In that case it doesn't matter if you postfix the constant with L, UL, or nothing. But if you write the same thing like
unsigned long x = 150 * 1000;
then the numbers 150 and 1000 are treated as (signed) int's and the multiplication is performed as that (by the compiler) with an int as result. x will get the value 18920 because of overflow (assuming 16 bit ints). To prevent that you can add UL (or L in this case) to one or both of the numbers or cast one or both of them.
Dear snigelen
you mean to say that in your example the operation will occur as follows:
unsigned long x = 150*1000;
First the multiplication on integers will occur with 150*1000 = 150000 as a result of this multiplication.
Thereafter since the int is of 16 bit so we will get 150000 truncated to 18928 ........ am I right upto here.
and finally the result will be implicitly upgraded to unsigned long of 18298 as value ..... right.
you mean to say that truncation will occur before the typecasting of the result to the unsigned long.
Please correct me if I got wrong understanding of your example.
Thanks and regards
First the multiplication on integers will occur with 150*1000 = 150000 as a result of this multiplication.
Thereafter since the int is of 16 bit so we will get 150000 truncated to 18928 ........ am I right upto here.
you mean to say that truncation will occur before the typecasting of the result to the unsigned long.
There is no type-casting.
The key thing is that the expression to the right of the assignment sign is evaluated first (without "looking" at the left hand side) and it only contains int's and the result is therefore an int. Then that resulting int is assigned to whatever is on the LHS. (If you had an uint8_t on LHS you'd get another truncation).
But someone that actually read the C standards may give a better explanation, I'm just trying to understand the language.
To be precise, the multiplication results in an overflow. For this particular case for most compilers, the result is 18928, however the compiler is free to do whatever it likes in the event of an overflow. For instance, a floating point overflow might result in #NAN. However I would not describe the process as "truncation". Mathematical truncation is removal of the least significant digits whereas integer overflow results in the loss of the most significant digits.
The key thing is that the expression to the right of the assignment sign is evaluated first (without "looking" at the left hand side) and it only contains int's and the result is therefore an int.
It is more restrictive than that. Evaluation of type and implied type promotion is handled on a per operator basis. So the following:
unsigned long x = 15000L - 150 * 1000;
would produce the wrong result because the multiplication is done first with ints, then the subtraction is done with longs, then the result is put into an unsigned long. So in this case two overflows would occur.
Hi koshchi
That's a pretty good example and also good brief explanation.
Can you or anybody on this forum point me some good links where I can get pretty good informative material about typecasting, arithematic overflow , mathematical overflow etc.
So that I can first of all make my C more sounding and also take care of these little but big tips in future in my programming.
Regards
I'm sort of assuming all C programmers have a copy of K&R? If not you should get one.
Ross,
I'd like to see you try!
(...runs for bomb shelter). *BOOM. Done*
And while I'm posting, @Steve17, in the example you just posted what do you think is gained by NOT making flag volatile?
Kicking off another thread wander - "bool"? really?