# How to check to see if a decimal is larger than 1.0 RSS

## 11 replies

Last post Nov 14, 2012 09:53 PM by Paul Linton

Participant

1054 Points

593 Posts

### How to check to see if a decimal is larger than 1.0

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

`if (var >1)`

I get:
Error 1 'decimal.operator >(decimal, decimal)': cannot explicitly call operator or accessor

All-Star

35860 Points

4900 Posts

ASPInsiders

Moderator

### Re: How to check to see if a decimal is larger than 1.0

try:

`if (var > 1.0M)`

The 'M' forces the number to be evaluated as a decimal (I've seen it work with a lower case 'm' also)

• Marked as answer by elmoWatson on Nov 13, 2012 01:12 PM

All-Star

31021 Points

6354 Posts

### Re: How to check to see if a decimal is larger than 1.0

dont use var : decimal varA; if (varA > 1.0)
Programming to simplify, dont look for hard way

All-Star

20513 Points

5712 Posts

### Re: How to check to see if a decimal is larger than 1.0

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.

Star

13403 Points

2531 Posts

### Re: How to check to see if a decimal is larger than 1.0

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.

Got a c# problem? Try .NET Book Zero from Charles Petzold, it's a free pdf.

All-Star

20513 Points

5712 Posts

### Re: How to check to see if a decimal is larger than 1.0

#### Paul Linton

decimal one = 1; \\ works

actually, the above will not compile ... you need to use forward slashes   B-)

decimal one = 1; // works

#### Paul Linton

How come  decimal one = 1; doesn't give an error?

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."

#### Paul Linton

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

not really ... look at the IL:

```IL_0001:  ldc.i4.1
IL_0002:  newobj      System.Decimal..ctor
IL_0007:  stloc.0```

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:

The stack transitional behavior, in sequential order, is:

1. 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.

#### Paul Linton

if (var > 1) is perfectly valid C#.

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:

```System.Decimal one = 1.0M;

IL_0001:  ldc.i4.s    0A
IL_0003:  ldc.i4.0
IL_0004:  ldc.i4.0
IL_0005:  ldc.i4.0
IL_0006:  ldc.i4.1
IL_0007:  newobj      System.Decimal..ctor
IL_000C:  stloc.0     ```

versus:

```System.Decimal one = 1;

IL_0001:  ldc.i4.1
IL_0002:  newobj      System.Decimal..ctor
IL_0007:  stloc.0   ```

```System.Decimal one = 1.0M;
if (one > 1.0M) ;

IL_0001:  ldc.i4.s    0A
IL_0003:  ldc.i4.0
IL_0004:  ldc.i4.0
IL_0005:  ldc.i4.0
IL_0006:  ldc.i4.1
IL_0007:  newobj      System.Decimal..ctor
IL_000C:  stloc.0
IL_000D:  ldloc.0
IL_000E:  ldc.i4.s    0A
IL_0010:  ldc.i4.0
IL_0011:  ldc.i4.0
IL_0012:  ldc.i4.0
IL_0013:  ldc.i4.1
IL_0014:  newobj      System.Decimal..ctor
IL_0019:  call        System.Decimal.op_GreaterThan
IL_001E:  ldc.i4.0
IL_001F:  ceq
IL_0021:  stloc.1
IL_0022:  ldloc.1
IL_0023:  brtrue.s    IL_0025```

versus

```System.Decimal one = 1;
if (one > 1) ;

IL_0001:  ldc.i4.1
IL_0002:  newobj      System.Decimal..ctor
IL_0007:  stloc.0
IL_0008:  ldloc.0
IL_0009:  ldc.i4.1
IL_000A:  newobj      System.Decimal..ctor
IL_000F:  call        System.Decimal.op_GreaterThan
IL_0014:  ldc.i4.0
IL_0015:  ceq
IL_0017:  stloc.1
IL_0018:  ldloc.1
IL_0019:  brtrue.s    IL_001B```

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.

Star

13403 Points

2531 Posts

### Re: How to check to see if a decimal is larger than 1.0

#### gerrylowry

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."

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.

Got a c# problem? Try .NET Book Zero from Charles Petzold, it's a free pdf.

All-Star

20513 Points

5712 Posts

### Re: How to check to see if a decimal is larger than 1.0

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.

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.

#### Paul Linton

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.

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

Star

13403 Points

2531 Posts

### Re: How to check to see if a decimal is larger than 1.0

#### gerrylowry

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.

Got a c# problem? Try .NET Book Zero from Charles Petzold, it's a free pdf.

Star

13403 Points

2531 Posts