【问题标题】:How can I write a symmetrical version of a snap to value formula (in C#)如何编写对齐值公式的对称版本(在 C# 中)
【发布时间】:2013-09-20 07:18:05
【问题描述】:

我想写一个组件,它可以将一个值向上移动一个增量,或者移动到最近的增量。

假设增量为 0.0005,对于 Up() 方法,以下是预期的输入和输出:

  • 1.0005 -> 1.0010(以增量方式移动)
  • 1.0006 -> 1.0010(不是增量,所以移动到增量)
  • 1.0007 -> 1.0010
  • 1.0008 -> 1.0010
  • 1.0009 -> 1.0010
  • 1.0010 -> 1.0015(以增量方式移动)
  • 1.0011 -> 1.0015
  • 1.0012 -> 1.0015

Down() 方法也会做同样的事情,相反。

我想出了这个公式:

return (value + increment) - (value % increment);

我预计 Down() 方法会类似,但我找不到它是什么。我能够让它工作的唯一方法是:

decimal mod = value % increment;

return mod != 0  ? value - mod : value - increment

当然,如果反过来操作相同,那么公式应该是相同的。

【问题讨论】:

  • 您可以创建一个函数,该函数枚举了所有值,并在向上/向下方向(您可以选择)上找到最接近给定值的函数。

标签: c# algorithm math equation


【解决方案1】:
    public static decimal Increment(decimal dec, decimal inc) {
        var mod = (dec % inc);
        return dec - Math.Abs(mod) + (inc < 0 && mod != 0 ? Math.Abs(inc) : 0) + inc;
    }

没有三元运算符:

    public static decimal Increment(decimal dec, decimal inc) {
        var mod = (dec % inc);
        var signInc = Math.Sign(inc);
        return dec - Math.Abs(mod) + 
              ((decimal)(Math.Pow(signInc, 2) - signInc) / 2) * 
                    Math.Abs(Math.Sign(mod)) * 
                    Math.Abs(inc)
                + inc;

    }

  ((decimal)(Math.Pow(signInc, 2) - signInc) / 2) * 
                    Math.Abs(Math.Sign(mod)) * 
                    Math.Abs(inc)

替换三元表达式。如果inc 为负数,Math.Pow(signInc, 2) - signInc) / 2 返回 1,否则返回 0。 Math.Abs(Math.Sign(mod)) 如果 mod 为 0,则返回 0,否则返回 1;如果inc &lt; 0 &amp;&amp; mod != 0,则使第一次乘法的结果为 1,否则为 0。

【讨论】:

  • 这绝对适用于两者,谢谢!有没有办法在不使用三元运算符的情况下做到这一点?我只是好奇胜过一切。好像三元对 Up 来说不是必需的,但 Down 也应该是必需的?
【解决方案2】:

公式

value - Abs(value % increment) + Abs(increment/2) + increment/2

以值 1.0006 为例,增量为 (+_)0.0005

当增量为+0.0005时

1.0006-0.0001+0.00025+0.00025 = 1.0010

当向下增量为-0.0005时

1.0006-0.0001+0.00025-0.00025 = 1.0005

【讨论】:

  • 我认为Down(1.0006) 应该给1.0005,而不是1.0000
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-03
  • 2011-09-08
  • 2023-03-15
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
相关资源
最近更新 更多