十进制和数学运算

问题描述 投票:18回答:10

我在C#中简单地转换了decimal。它看起来像这样:

private decimal BaseValue
{
    get; set;
}

public decimal ConvertedValue 
{
    get
    {
        return BaseValue * (365 / 360);
    }
}

但是,这不起作用。我假设因为C#正在处理分数中的数字作为整数。所以我可以这样做(有效):

public decimal ConvertedValue 
{
    get
    {
        return BaseValue * (decimal)((double)365 / (double)360);
    }
}

现在这看起来有点像矫枉过正,但我​​可以忍受。我的主要问题是:

为什么Visual Studio警告我,'演员是多余的',对于(double)演员?如果我删除(double)演员,那么(decimal)演员变得多余。如果我删除它,那么我回到解决方案,这是行不通的。救命...?

c# casting decimal operands
10个回答
23
投票

解决这个问题的一种方法是指定计算中的数字是decimal,最后是m

return BaseValue * (365m / 360m);

为什么Visual Studio会警告我,对于(双)强制转换,“强制转换是多余的”

因为当你在等式的一边有一个double时,结果将是一个双倍。

(double)365 / (double)360

看看the documentation of the * operator overloads。您将看到操作数总是与以下类型相同:

decimal operator *(decimal x, decimal y);


...然后(十进制)演员变得多余。

再次,因为当你在等式的一边有一个decimal时,结果将是一个小数:

BaseValue * (decimal)(365 / 360)

这里的问题是范围!你将该师的整个结果投到了decimal。实际上你可以通过删除括号来解决你的问题:

return BaseValue * 365 / 360;

这种方式你的方程式是正确的,因为*乘法的结果将是一个decimal(因为其中一个操作数是decimal,所以另一个将被隐式地输入)并且再次除法的结果也将是小数同样的道理。

注意:删除括号通常与将它们保留在一起不同。在某些情况下,当这些操作的顺序发生变化时,浮点运算的结果会有所不同,即使这两个表达式在数学上是相同的。 Banex的评论

编辑:

m thingy被称为文字。有关所有类型后缀或文字的更多信息,请访问documentation here


0
投票

(双)演员中的任何一个都是多余的,但不是两者。如果操作的任何参数是double,则另一个参数会自动转换为double。你能将其中一个参数写成实数常量,例如365.0吗?


8
投票

decimal强制转换是多余的,因为编译器知道你想要返回一个decimal

两个double演员阵容中的一个是多余的,因为当你将其中一个ints投射到double时,很明显你使用double除法运算符而不是整数除法。

但它应该足以使用decimal文字后缀m

return BaseValue * (365m / 360);

同样,一个m足以推断出正确的算子。


但是,嘿,BaseValue已经是decimal并且括号没有意义(如果你不想要整数除法)......这也应该有用:

return BaseValue * 365 / 360;

4
投票

使用m后缀:

return 365m/360 * BaseValue;

4
投票

某些类型的数字有一些后缀,例如:

 // Use long suffix.
 long l1 = 10000L;

 // Use double suffix.
 double d1 = 123.764D;

 // Use float suffix.
 float f1 = 100.50F;

 // Use unsigned suffix.
 uint u1 = 1000U;

 // Use decimal suffix.
 decimal m2 = 4000.1234M;

 // Use unsigned suffix and long suffix.
 ulong u2 = 10002000300040005000UL;

后缀指定数字类型。它们指示C#编译器将诸如1000之类的整数文字视为某种类型的数字 - 例如,长(1000L)。我们将研究如何为数字添加数字后缀。

在你的情况下:

public decimal ConvertedValue 
{
    get
    {
        return BaseValue * (365 / 360M);
    }
}

当你使用大写后缀时,它也更清晰:

小写后缀。您还可以指定小写后缀,例如u,l,ul,f,d和m。但这些更容易与数字混淆。字母'l'有时被视为数字1。


4
投票

你可以只为其中一个数字添加一个m后缀,使其成为十进制:

return BaseValue * (365 / 360m);

2
投票

您可以使用m后缀简单地使用小数文字:

public decimal ConvertedValue 
{
    get
    {
        return BaseValue * (365m/360);
    }
}

第二次演员是多余的原因是因为C#导出你的((double)365 / (double)360)表达式中的第一个数字(365)是double。因此,为了计算除法,它还将隐含地将第二项转换为double。所以你是否把(double)写成第二个元素并不重要:

csharp> (double) 365/350        
1.04285714285714                
csharp> (double) 365/ (double) 350
1.04285714285714

然而,投射到双打然后回到小数是没有用的。通过在表达式中使用一个十进制文字,另一个数字也将是一个小数,因此我们留在decimal世界。


2
投票

在您的示例中,您可以将括号放在一边:

return BaseValue*365/360;

2
投票

你只需要一个双重演员。所以

return BaseValue * (decimal)(365/(double)360);

会很好的。

一旦为double,编译器就会将其视为非整数除法。

另外

return (BaseValue*365)/360;

将工作。

甚至

return BaseValue*365/360;

因为乘法的优先级高于除法。


0
投票

双倍除以双倍(当然)双倍。因此,投射结果是多余的。

如果您只是将数字指定为小数,则会更短:

 return BaseValue * (365m /360);
© www.soinside.com 2019 - 2024. All rights reserved.