5

I'm trying to make a simple feet to meter converter, but this happens:

using System;
using System.Windows;
using System.Windows.Controls;

namespace CoolConversion
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        decimal feet;
        decimal meter;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            feet = Convert.ToDecimal(Feet.Text);
            meter = feet / 3.281;
        }
    }
}

This is the code I have currently. At first, feet & meter were int, but I couldn't divide an int by 3.281. I changed them to decimals and now I have this error:

Error CS0019 Operator '/' cannot be applied to operands of type 'decimal' and 'double'

If I can't divide decimals by ints, and if I can't use the / symbol on decimals, how am I supposed to divide by decimals?

Mathieu VIALES
  • 4,526
  • 3
  • 31
  • 48
JaxBen98
  • 53
  • 7
  • 2
    Convert `3.281` to a decimal as well? You can use a literal suffix to write it as `3.281m`. – hnefatl Jan 16 '19 at 15:08
  • You need to tell C# that your constant is a decimal by adding an 'm' like this `meter = feet / 3.281m;`. Alternatively you can make your variables doubles. – Hans Kilian Jan 16 '19 at 15:09
  • 1
    Try `meter = feet / 3.281m` using just `3.281` tells the compiler to use a `double` while `3.281f` tells it to use a `float`. Likewise, `3.281m` tells it to use `decimal`. – Hazel へいぜる Jan 16 '19 at 15:10
  • Possible duplicate of [C# short/long/int literal format?](https://stackoverflow.com/questions/5820721/c-sharp-short-long-int-literal-format) – Cleptus Jan 16 '19 at 15:12
  • 1
    @bradbury9 I wouldn't say it's quite a duplicate of that particular post since the OP there knew what suffix specification was. I definitely believe that is a useful post for future readers though! – Hazel へいぜる Jan 16 '19 at 15:48

2 Answers2

5

The issue here is that the compiler is thinking that your constant 3.281 is of type double. If you intend to use a type such as decimal you'll have to append the m suffix. Likewise with float types you have to append the f suffix. Per MSDN:

By default, a real numeric literal on the right side of the assignment operator is treated as double.


float

Therefore, to initialize a float variable, use the suffix f or F, as in the following example:
float x = 3.5F;


double

However, if you want an integer number to be treated as double, use the suffix d or D, for example:
double x = 3D;


decimal

If you want a numeric real literal to be treated as decimal, use the suffix m or M, for example:
decimal myMoney = 300.5m;


My Advice

You should really determine which type you'll actually be needing to use prior to using it. In the case of converting feet to meters I would use either double or float; double is typically the case because it is more precise.

private double feet = 0.0d;
private double meters = 0.0d;

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
    feet = Convert.ToDouble(Feet.Text);
    meters = feet / 3.281d;
}

The decimal type is typically used to hold monetary values, where double and float are used for calculations such as this. Also, it's not a requirement, but if you're ever working with multiple similar types such as the case of float, double, decimal; it's always a good idea to use the suffix for each to clearly relay which type you're intending to use.


Final Note

You can cast to decimal as others have pointed out, but it's an unnecessary cast when you can just specify decimal by using 3.281m. In an environment where performance matters, you should avoid unnecessary casting whenever possible.

On another note, you should really ensure that the text you're attempting to convert is a valid value prior to attempting to convert it. I prefer to use TryParse (all numeric types should have a TryParse method if I remember correctly). The reasoning behind this is that if I type 123a into your text box with the way your method currently works, it'll blow up right then and there. Fixing this is really straight forward:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
    if (double.TryParse(Feet.Text, out feet))
        meters = feet / 3.281d;
    else
        MessageBox.Show($"You've entered an invalid value: {Feet.Text}.");
}
Hazel へいぜる
  • 2,751
  • 1
  • 12
  • 44
4

By default, 3.281 by itself is a double floating point precision number. You can use the decimal-literal notation by adding a m to the end of the number.

meter = feet / 3.281m;

For brevity sake, if you're ever using a variable that is declared as a double you can always just cast it to a decimal in the event you need to perform a calculation with two different types in each operand.

double feetToMeterValue = 3.281;
meter = feet / (decimal)feetToMeterValue;

This works for other types as well, but just be aware you will lose precision when casting to specific types i.e. double > float and the more obvious decimal to int.

Chris
  • 2,254
  • 8
  • 22
  • 2
    casting vs exclicit declaring the correct type. I would definitely go the second choice. – Cleptus Jan 16 '19 at 15:12
  • @bradbury9 Updated to add a bit more brevity to the answer, because explicit initialization is the better answer; you're right. But casting will always have it's uses as well so it's worth noting. – Chris Jan 16 '19 at 15:17