gpt4 book ai didi

c# - 使用 int 作为除数时计算公式的最佳方法是什么

转载 作者:太空狗 更新时间:2023-10-30 01:10:55 25 4
gpt4 key购买 nike

我经常发现自己有一个表达式,其中除以 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 时,“四舍五入”为 1。所以我发现自己有将 c 转换为 double,然后由于这使表达式也成为 double,因此将整个表达式转换为 int。此代码如下所示:

int a = 2;
int b = 4;
int c = 5;
int d = (int)(a * (b / (double)c));

在这个小例子中它还不错,但在一个大的公式中它变得相当困惑。

此外,我猜转换会对性能产生(小)影响。

所以我的问题基本上是,是否有比同时转换除数和结果更好的方法。

我知道在这个例子中,将 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 的两倍。

最佳答案

免责声明:我把所有这些都打出来了,然后我想,我应该发布这个吗?我的意思是,这是一个非常糟糕的想法,因此不会真正帮助 OP...最后我想,嘿,我已经输入了全力以赴;我不妨继续并单击“发布您的答案”。尽管这是一个“坏”主意,但它有点有趣(无论如何对我来说)。因此,也许您会通过阅读它以某种奇怪的方式受益。

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


这是一个完全疯狂的想法。

我实际上不建议将其放入任何类型的生产环境中,根本,因为我确实刚刚想到了它,这意味着我还没有真正彻底考虑过,我敢肯定它有大约十亿个问题。这只是一个想法。

但基本概念是创建一个可用于算术表达式的类型,在内部对表达式中的每个术语使用 double,仅作为所需类型进行评估(在本例中: int) 在结尾

您将从这样的类型开始:

// 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();
}
}

然后您将定义到/从 double隐式 转换以及您要支持的类型(再次:int) .像这样:

public static implicit operator Term(int x)
{
return new Term((double)x);
}

public static implicit operator int(Term x)
{
return (int)x._value;
}

// ...and so on.

接下来,自己定义操作:PlusMinus 等。对于您的示例代码,我们需要 Times (对于*)和DividedBy(对于/):

public Term Times(Term multiplier)
{
// This would work because you would've defined an implicit conversion
// from double to Term.
return _value * multiplier._value;
}

public Term DividedBy(Term divisor)
{
// Same as above.
return _value / divisor._value;
}

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

public static class TermHelper
{
public static Term Times(this int number, Term multiplier)
{
return ((Term)number).Times(multiplier);
}

public static Term DividedBy(this int number, Term divisor)
{
return ((Term)number).DividedBy(divisor);
}
}

这一切会给您带来什么? 几乎没有!但它会清理你的表达式,隐藏所有那些难看的显式转换,使你的代码明显更具吸引力并且更不可能调试。 (再说一次,这不是背书,只是一个疯狂的想法。)

所以不是这个:

int d = (int)(a * (b / (double)c)); // Output: 2

你会有这个:

int d = a.Times(b.DividedBy(c)); // Output: 2

值得吗?

好吧,如果不得不编写强制转换操作是世界上最糟糕的事情,比如,甚至比依赖过于聪明的代码更糟糕,那么也许这样的解决方案值得追求。

由于上述显然不正确...答案是非常明确的。但我只是想无论如何我都会分享这个想法,以表明这样的事情(也许)是可能的。

关于c# - 使用 int 作为除数时计算公式的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3682755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com