Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当使用整数作为除数时,计算公式的最佳方法是什么_C#_.net - Fatal编程技术网

C# 当使用整数作为除数时,计算公式的最佳方法是什么

C# 当使用整数作为除数时,计算公式的最佳方法是什么,c#,.net,C#,.net,我经常发现自己有一个表达式,其中除以int是一个大公式的一部分。我将给你一个简单的例子来说明这个问题: int a = 2; int b = 4; int c = 5; int d = a * (b / c); 在本例中,d如预期的那样等于0,但我希望它是1,因为4/5乘以2等于1 3/5,当转换为int get时,它的“舍入”为1。所以我发现自己必须将c转换为double,然后因为这使表达式也成为double,所以将整个表达式转换为int int a = 2; int b = 4; int

我经常发现自己有一个表达式,其中除以int是一个大公式的一部分。我将给你一个简单的例子来说明这个问题:

int a = 2;
int b = 4;
int c = 5;
int d = a * (b / c);
在本例中,d如预期的那样等于0,但我希望它是1,因为4/5乘以2等于1 3/5,当转换为int get时,它的“舍入”为1。所以我发现自己必须将c转换为double,然后因为这使表达式也成为double,所以将整个表达式转换为int

int a = 2;
int b = 4;
int c = 5;
int d = (int)(a * (b / (double)c));
// Probably you'd make this implement IEquatable<Term>, IEquatable<double>, etc.
// Probably you'd also give it a more descriptive, less ambiguous name.
// Probably you also just flat-out wouldn't use it at all.
struct Term
{
    readonly double _value;

    internal Term(double value)
    {
        _value = value;
    }

    public override bool Equals(object obj)
    {
        // You would want to override this, of course...
    }

    public override int GetHashCode()
    {
        // ...as well as this...
        return _value.GetHashCode();
    }

    public override string ToString()
    {
        // ...as well as this.
        return _value.ToString();
    }
}
在这个小例子中,它并没有那么糟糕,但在一个大的公式中,它是相当混乱的

另外,我猜演员阵容会对表演产生(小)影响

所以我的问题基本上是,除了计算除数和结果,是否还有更好的方法

我知道在这个例子中,将a*(b/c)更改为(a*b)/c可以解决问题,但在更大的实际场景中,进行此更改是不可能的

编辑(从现有程序中添加案例):

在本例中,我根据滚动条的大小及其容器的大小计算滚动条的位置。因此,如果页面上有两个元素要适合,滚动条将是容器高度的一半,如果我们滚动了可能的一半元素,这意味着滚动器位置应该向下移动1/4,这样它将驻留在容器的中间。计算工作正常,显示良好。我只是不喜欢我的代码中的表达式

代码的重要部分放在这里并附加在这里:

int scrollerheight = (menusize.Height * menusize.Height) / originalheight;
int maxofset = originalheight - menusize.Height;
int scrollerposition = (int)((menusize.Height - scrollerheight) * (_overlayofset / (double)maxofset));
这里的originalheight是所有元素的高度,因此在上述情况下,这将是menusize.height的两倍。

首先,C#截断int除法的结果,当转换为int时,没有舍入


如果不进行任何转换,就不可能先进行b/c转换。

免责声明:我把所有这些都打出来了,然后我想,我应该发布这些吗?我的意思是,这是一个非常糟糕的想法,因此对手术没有帮助。。。最后我想,嘿,我已经把它都打出来了;我不妨继续点击“发布你的答案”。尽管这是一个“坏”主意,但还是有点有趣(无论如何,对我来说)。所以也许你会从中受益

出于某种原因,我怀疑上述免责声明不会保护我不受反对票的影响,尽管


这是一个完全疯狂的想法。 实际上,我不建议将其应用于任何类型的生产环境,因为我刚才确实想到了它,这意味着我还没有真正彻底地考虑过它,我确信它存在大约10亿个问题。这只是一个想法

但基本概念是创建一个可用于算术表达式的类型,在内部为表达式中的每个术语使用一个
double
,最后只作为所需的类型进行计算(在本例中:
int

您可以从以下类型开始:

int a = 2;
int b = 4;
int c = 5;
int d = (int)(a * (b / (double)c));
// Probably you'd make this implement IEquatable<Term>, IEquatable<double>, etc.
// Probably you'd also give it a more descriptive, less ambiguous name.
// Probably you also just flat-out wouldn't use it at all.
struct Term
{
    readonly double _value;

    internal Term(double value)
    {
        _value = value;
    }

    public override bool Equals(object obj)
    {
        // You would want to override this, of course...
    }

    public override int GetHashCode()
    {
        // ...as well as this...
        return _value.GetHashCode();
    }

    public override string ToString()
    {
        // ...as well as this.
        return _value.ToString();
    }
}
接下来,定义操作本身:
加上
减去
,等等。对于示例代码,我们需要
(对于
*
)和
除以
(对于
/
):

最后,编写一个
static
helper类,使您能够对想要使用的任何类型(可能只是
int
)执行基于
Term
的操作:

这一切能给你带来什么<几乎什么都没有
但它会清理您的表达式,隐藏所有难看的显式强制转换,使您的代码更具吸引力,也更不可能调试。(再一次,这不是认可,只是一个疯狂的想法。)

因此,与此相反:

int d = (int)(a * (b / (double)c)); // Output: 2
你会有这个:

int d = a.Times(b.DividedBy(c)); // Output: 2
值得吗? 好吧,如果不得不编写强制转换操作是世界上最糟糕的事情,比如,甚至比依赖过于聪明的代码更糟糕,那么也许这样的解决方案值得追求


由于上述情况显然不是真的。。。答案是一个非常明确的否定。但我想我还是要分享这个想法,以证明这样的事情(也许)是可能的。

将b乘以100。然后在末尾除以100。

在这种情况下,我建议使用双精度,因为不需要精确的精度


但是,如果您真的想在不使用浮点运算的情况下完成这一切,我建议您创建某种分数类,它要复杂得多,效率要低得多,但您可以跟踪所有的除数和除数,然后一次计算所有除数和除数。

如果一个明显的解决方案(模溢出)不适用于您的实际情况,也许你可以举一个真实案例的例子。否则,我们的任何建议都可能同样无效。我在上面的问题上添加了一个编辑,给出了一个来自当前程序的示例(实际上是让我首先写这个问题的示例:))如果你知道你需要float/double,为什么要使用int?计算中的任何元素都不需要float/double,也不是它的结果。问题是,由于_overlayofset在所有情况下都小于maxofset,如果没有此强制转换,结果将始终计算为0。我同意你的观点。也许不值得,但这是一个非常有趣的思想实验。感谢您花时间完成所有这些工作。这当然会起作用,但在代码中看起来会更加混乱。再乘以100,再除以100,我的性能会比两次强制转换更高,所以我觉得这个解决方案比当前实现的解决方案差。是的。一个double当然可以,但是我想知道是否有使用int的解决方案,但是我开始认为这是不好的
int d = a.Times(b.DividedBy(c)); // Output: 2