FWIW, varA is also not a good choice ... it's too general; imho, it's essential to use meaningful names.
BTW, your code would get this error: "Operator '>' cannot be applied to operands of type 'decimal' and 'double'"; as per the example provided by
augustwind, you need the
M after the 1.0:
"if you want a numeric real literal to be treated as
decimal, use the suffix m or
M"
g.
B-) Please help me by completing my school survey about computer programmers on my website. Thank you!!! Gerry Lowry +1 705-429-7550 wasaga beach, ontario, canada
The M suffix is the best way to go but you can also do
if (var.CompareTo(1) > 0)
The main thing, however, is to build your skill in understanding error messages.
The first error message tells you that the first operand of the '>' operator is decimal, that makes sense - it was declared as decimal. The error message says that the second operand is a double, that also makes sense - it should seem reasonable that 1.0
is treated as a double. So, the problem is how do you express the concept of oneness as a decimal. You could have
decimal one = 1; \\ works
but this is a bit deceptive as you would find if what you wanted was a half
decimal half = 0.5; \\ error
gives you an error, but this time the error is really helpful, it says
Literal of type double cannot be implicitly converted to type 'decimal'; use an 'M' suffix to create a literal of this type.
Wow, lots of good information. A double cannot be implicitly (without asking for it) converted to a decimal. But also, if I want a literal of type decimal I need to append an 'M'.
The problem with using help or searching on the internet is that you need a certain amount of knowledge of terminology before you can frame good questions. One piece of information that this error message teaches you is that when you write 1 or 0.5 then
that is called a literal. When I saw the original error message you posted I realised that you needed to specify a decimal literal because I have bumped into the concept of literals in the past. Now it is really easy, just google 'C# how do I specify a decimal
literal' and the answer is right in the search results.
How come decimal one = 1; doesn't give an error? Good question. The reason is that 1 is not treated as a double literal but rather as an int is basically because it has no decimal point and it is small enough to be represented as an int (if it was more
than a few billion it would be a long). An int (or a long) can be exactly converted to a decimal and so the compiler will implicitly convert the 1 (an int literal) to a decimal. Interestingly, a double cannot always be converted to a decimal because doubles
have a larger range (but less precision) than a decimal. Doubles can be up to 10^308 and decimals go to a mere 10^28, which is why you got the very first error message.
As to your second error message, I am afraid that you are not giving us the full story because if (var > 1) is perfectly valid C#. The 1 is an int which will be implicitly converted to a decimal and then the comparison will succeed. So some of the code
that you have not shown is causing this message.
The reason is that 1 is not treated as a double literal but rather as an int is basically because it has no decimal point and it is small enough to be represented as an int
although using the M suffix is visually more correct to the
human programmer imho, the simple 1 generates substantially less
IL.
FWIW, it might be interesting to study what happens inside of "Decimal Constructor (Int32)".
g.
B-) Please help me by completing my school survey about computer programmers on my website. Thank you!!! Gerry Lowry +1 705-429-7550 wasaga beach, ontario, canada
That is not the answer. That only comes in to play once the compiler works out the type of '1'. My post explained why '1' is treated as an int (lack of non-int characters and size of the value). My answer then proceeds to explain that because it is an
int the implicit conversion can be used.
gerrylowry
not really ... look at the IL:
Yes really. What you need to work out is why is that IL generated. All the IL confirms is that the compiler has determined that '1' is an int and so it is OK to pass it to the constructor. How literal values are interpreted is the source of the
confusion in the original post. Merely saying that if you write correct code then IL is generated adds nothing to the discussion.
gerrylowry
yes, it is perfectly valid c#,
I know that, that's why I wrote it
gerrylowry
however, imho, stylistically, it's better to write
You tried to make this point in an earlier post, why repeat yourself? It's OK you are allowed to have an opinion, no one is disputing that. At no point did I make any comment at all regarding style (basically because the question was obviously only for
sample purposes and stylistic comments seemed to me to be a distration and others had made them). Other people can make style comments if they think it is useful but there is no need to repeat yourself.
gerrylowry
the programmer is demonstrating visually that var is a System.Double
var is not a System.Double and the statement does not demonstrate that it is.
gerrylowry
using the M suffix is visually more correct to the human
programmer
Without the M sufffix it is an int literal, with the M suffix it is a decimal literal. It is neither more correct nor more incorrect. It is neither visual nor tactile or any other sense. It just is.
Paul, we may have to agree to disagree ... the compiler is parsing source code ... as you stated, because the
1 stands by itself, the compiler recognizes it as a literal for the integer value one ... so
the reason, imho, that it works is because the variable on the left side of the assignment is a System.Decimal and because "there is a
predefined implicit conversion from int to
long,
float, double, or
decimal" the
c# compiler selects the "Decimal Constructor (Int32)".
Paul Linton
you need to work out is why is that IL generated.
it's obvious because the assignment is to a System.Decimal and therefore the result must be a System.Decimal whose value is arithmetically equivalent to the number one.
You tried to make this point in an earlier post, why repeat yourself?
simple answer. as a programmer for 45+ years, style is important. likewise, awareness of compiler behaviour is important. sometimes it's necessary to weigh trade offs of style versus what the compiler generates, although that's
a slippery slope because the compiler is an evolving target ... in this case, knowing that my preferred "System.Decimal one = 1.0M;" generates substantially more core than "System.Decimal one = 1;", i would choose to sacrifice style and trust
future versions of the c# compiler not to double-cross me.
"Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live."
Paul, thank you for spotting my typo ... my brain intended to write "because the programmer is demonstrating visually that
var is a System.Decimal" by my fingers mutinied; i've corrected the previous reply and given my fingers a time out.
B-)
regards ~~ gerry
B-) Please help me by completing my school survey about computer programmers on my website. Thank you!!! Gerry Lowry +1 705-429-7550 wasaga beach, ontario, canada
because the programmer is demonstrating visually that var is a
System.Decimal
I knew you made a typo, that was obvious. But even with the typo corrected the statement is not correct. In 'if (var > 1.0M)' var may be an int, sbyte, byte, short, ushort, uint, long, ulong or char and the code would still compile and run without error.
elmoWatson
Participant
1054 Points
593 Posts
How to check to see if a decimal is larger than 1.0
Nov 13, 2012 12:48 PM|LINK
How do you check to see if a decimal value is greater than another value?
I tried this:
decimal var;
if (var > 1.0)
but I get:
Error 2 Operator '>' cannot be applied to operands of type 'decimal' and 'double'
if I try
I get:
Error 1 'decimal.operator >(decimal, decimal)': cannot explicitly call operator or accessor
augustwind
All-Star
35860 Points
4900 Posts
ASPInsiders
Moderator
Re: How to check to see if a decimal is larger than 1.0
Nov 13, 2012 01:07 PM|LINK
try:
The 'M' forces the number to be evaluated as a decimal (I've seen it work with a lower case 'm' also)
All Things Dot Net
Stored Procs and Code in a Flash!
ASP.Net Sitemap Creator
oned_gk
All-Star
31021 Points
6354 Posts
Re: How to check to see if a decimal is larger than 1.0
Nov 13, 2012 01:24 PM|LINK
gerrylowry
All-Star
20513 Points
5712 Posts
Re: How to check to see if a decimal is larger than 1.0
Nov 13, 2012 02:36 PM|LINK
@ oned_gk
i agree with you: imho, a best practice is to absolutely avoid using contextual keywords http://msdn.microsoft.com/en-us/library/the35c6y.aspx as variable names.
FWIW, varA is also not a good choice ... it's too general; imho, it's essential to use meaningful names.
BTW, your code would get this error: "Operator '>' cannot be applied to operands of type 'decimal' and 'double'"; as per the example provided by augustwind, you need the M after the 1.0:
if (varA > 1.0M) ...
@ augustwind, yes, in this case, case does not matter: http://msdn.microsoft.com/en-us/library/364x0z75(v=vs.110).aspx
"if you want a numeric real literal to be treated as decimal, use the suffix m or M"
g.
Paul Linton
Star
13403 Points
2531 Posts
Re: How to check to see if a decimal is larger than 1.0
Nov 13, 2012 09:11 PM|LINK
The M suffix is the best way to go but you can also do
if (var.CompareTo(1) > 0)
The main thing, however, is to build your skill in understanding error messages.
The first error message tells you that the first operand of the '>' operator is decimal, that makes sense - it was declared as decimal. The error message says that the second operand is a double, that also makes sense - it should seem reasonable that 1.0 is treated as a double. So, the problem is how do you express the concept of oneness as a decimal. You could have
decimal one = 1; \\ works
but this is a bit deceptive as you would find if what you wanted was a half
decimal half = 0.5; \\ error
gives you an error, but this time the error is really helpful, it says
Literal of type double cannot be implicitly converted to type 'decimal'; use an 'M' suffix to create a literal of this type.
Wow, lots of good information. A double cannot be implicitly (without asking for it) converted to a decimal. But also, if I want a literal of type decimal I need to append an 'M'.
The problem with using help or searching on the internet is that you need a certain amount of knowledge of terminology before you can frame good questions. One piece of information that this error message teaches you is that when you write 1 or 0.5 then that is called a literal. When I saw the original error message you posted I realised that you needed to specify a decimal literal because I have bumped into the concept of literals in the past. Now it is really easy, just google 'C# how do I specify a decimal literal' and the answer is right in the search results.
How come decimal one = 1; doesn't give an error? Good question. The reason is that 1 is not treated as a double literal but rather as an int is basically because it has no decimal point and it is small enough to be represented as an int (if it was more than a few billion it would be a long). An int (or a long) can be exactly converted to a decimal and so the compiler will implicitly convert the 1 (an int literal) to a decimal. Interestingly, a double cannot always be converted to a decimal because doubles have a larger range (but less precision) than a decimal. Doubles can be up to 10^308 and decimals go to a mere 10^28, which is why you got the very first error message.
As to your second error message, I am afraid that you are not giving us the full story because if (var > 1) is perfectly valid C#. The 1 is an int which will be implicitly converted to a decimal and then the comparison will succeed. So some of the code that you have not shown is causing this message.
gerrylowry
All-Star
20513 Points
5712 Posts
Re: How to check to see if a decimal is larger than 1.0
Nov 13, 2012 11:57 PM|LINK
@ Paul Linton
actually, the above will not compile ... you need to use forward slashes B-)
decimal one = 1; // works
The answer is in the c# language reference: http://msdn.microsoft.com/en-us/library/5kzh1b5w.aspx "int (C# Reference)"
"There is a predefined implicit conversion from int to long, float, double, or decimal."
not really ... look at the IL:
Note from the IL that the integer literal 1 is passed to System.Decimal's constructor.
System.Decimal is a struct; if you look at its eight contructors here http://msdn.microsoft.com/en-us/library/system.decimal.aspx, you will notice http://msdn.microsoft.com/en-us/library/hk63d62d.aspx "Decimal Constructor (Int32)".
The literal 1 becomes an Int32 via ldc.i4.1:
http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldc_i4_1(v=vs.110).aspx
"OpCodes.Ldc_I4_1 Field"
The stack transitional behavior, in sequential order, is:
The value 1 is pushed onto the stack.
This is a special short encoding for the push of the integer value 1.
(the MSDN page currently reads 0 ... that's a typo.)
All special short encodings push 4 byte integers on the stack.
yes, it is perfectly valid c#, however, imho, stylistically, it's better to write:
if (var > 1.0M)
because the programmer is demonstrating visually that var is a System.Decimal.
MORE INFORMATION
compare the IL:
versus:
adding the if:
versus
although using the M suffix is visually more correct to the human programmer imho, the simple 1 generates substantially less IL.
FWIW, it might be interesting to study what happens inside of "Decimal Constructor (Int32)".
g.
Paul Linton
Star
13403 Points
2531 Posts
Re: How to check to see if a decimal is larger than 1.0
Nov 14, 2012 12:28 AM|LINK
That is not the answer. That only comes in to play once the compiler works out the type of '1'. My post explained why '1' is treated as an int (lack of non-int characters and size of the value). My answer then proceeds to explain that because it is an int the implicit conversion can be used.
Yes really. What you need to work out is why is that IL generated. All the IL confirms is that the compiler has determined that '1' is an int and so it is OK to pass it to the constructor. How literal values are interpreted is the source of the confusion in the original post. Merely saying that if you write correct code then IL is generated adds nothing to the discussion.
I know that, that's why I wrote it
You tried to make this point in an earlier post, why repeat yourself? It's OK you are allowed to have an opinion, no one is disputing that. At no point did I make any comment at all regarding style (basically because the question was obviously only for sample purposes and stylistic comments seemed to me to be a distration and others had made them). Other people can make style comments if they think it is useful but there is no need to repeat yourself.
var is not a System.Double and the statement does not demonstrate that it is.
Without the M sufffix it is an int literal, with the M suffix it is a decimal literal. It is neither more correct nor more incorrect. It is neither visual nor tactile or any other sense. It just is.
gerrylowry
All-Star
20513 Points
5712 Posts
Re: How to check to see if a decimal is larger than 1.0
Nov 14, 2012 08:34 AM|LINK
@ Paul Linton
Paul, we may have to agree to disagree ... the compiler is parsing source code ... as you stated, because the 1 stands by itself, the compiler recognizes it as a literal for the integer value one ... so the reason, imho, that it works is because the variable on the left side of the assignment is a System.Decimal and because "there is a predefined implicit conversion from int to long, float, double, or decimal" the c# compiler selects the "Decimal Constructor (Int32)".
it's obvious because the assignment is to a System.Decimal and therefore the result must be a System.Decimal whose value is arithmetically equivalent to the number one.
N.B.: in hexadecimal, ldc.i4.1 is 17. see http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldc_i4_1(v=vs.110).aspx.
simple answer. as a programmer for 45+ years, style is important. likewise, awareness of compiler behaviour is important. sometimes it's necessary to weigh trade offs of style versus what the compiler generates, although that's a slippery slope because the compiler is an evolving target ... in this case, knowing that my preferred "System.Decimal one = 1.0M;" generates substantially more core than "System.Decimal one = 1;", i would choose to sacrifice style and trust future versions of the c# compiler not to double-cross me.
put another way, as you yourself have mentioned from http://www.codinghorror.com/blog/2008/06/coding-for-violent-psychopaths.html:
"Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live."
Paul, thank you for spotting my typo ... my brain intended to write "because the programmer is demonstrating visually that var is a System.Decimal" by my fingers mutinied; i've corrected the previous reply and given my fingers a time out. B-)
regards ~~ gerry
Paul Linton
Star
13403 Points
2531 Posts
Re: How to check to see if a decimal is larger than 1.0
Nov 14, 2012 07:55 PM|LINK
Paul Linton
Star
13403 Points
2531 Posts
Re: How to check to see if a decimal is larger than 1.0
Nov 14, 2012 07:56 PM|LINK
I forgot, there is also a chance that var may be decimal.