草庐IT

c++ - 将while循环变成数学方程式?

coder 2023-06-01 原文

我的程序中有两个简单的 while 循环,我觉得应该是数学方程,但我正在努力转换它们:

float a = someValue;
int b = someOtherValue;
int c = 0;

while (a <= -b / 2) {
    c--;
    a += b;
}
while (a >= b / 2) {
    c++;
    a -= b;
}

此代码按原样工作,但我觉得它可以简化为数学方程式。这里的想法是该代码采用偏移量 (someValue) 并调整坐标 (c) 以最小化与图 block 中心的距离(大小为 someOtherValue)。任何帮助将不胜感激。

最佳答案

可以证明以下是正确的:

c = floor((a+b/2)/b)
a = a - c*b

注意 floor 表示向下舍入,朝向负无穷:不是朝向 0。(例如 floor(-3.1)=-4。floor() 库函数会执行此操作;请确保不要只转换为 int,通常会向 0 舍入。)

大概 b 是严格正数,否则两个循环都不会终止:添加 b 不会使 a 变大而减去 b 不会使 a 更小。有了这个假设,我们可以证明上面的代码有效。 (而且 paranoidgeek 的代码也几乎是正确的,只是它使用强制转换为 int 而不是 floor。)

巧妙的证明方法: 代码在 a 中加或减 b 的倍数,直到 a[-b/2,b/2),您可以将其视为从 a/b 中添加或减去 整数,直到 a/b[-1/2,1/2),即直到 (a/b+1/2)(称之为 x)在 [0,1 )。由于您只是通过整数更改它,所以 x 的值不会更改 mod 1,即它会转到它的 remainder mod 1,这是 x-floor(x)。所以你做的有效减法数(即c)是floor(x)

繁琐的证明方式:

<子> 在第一个循环结束时,c的值是循环运行次数的负数,即:

  • 0 如果:a > -b/2 <=> a+b/2 > 0
  • -1 如果:-b/2 ≥ a > -3b/2 <=> 0 ≥ a+b/2 > -b <=> 0 ≥ x > -1
  • -2 如果:-3b/2 ≥ a > -5b/2 <=> -b ≥ a+b/2 > -2b <=> -1 ≥ x > -2 等等,

其中 x = (a+b/2)/b,因此 c 为:如果 x>0,则为 0,否则为“ceiling(x)-1”。如果第一个循环完全运行,那么在 最后一次执行循环之前它是 ≤ -b/2,所以它现在是 ≤ -b/2+b,即 ≤ b/2 .根据它是否恰好是 b/2(即,您开始时 x 是否恰好是一个非正整数),第二个循环恰好运行 1 次或 0,而 c 是天花板(x)或天花板(x)-1。这样就解决了第一个循环运行时的情况。

如果第一个循环没有运行,那么第二个循环结束时 c 的值为:

  • 0 如果:a < b/2=""><=> a-b/2 <>
  • 1 如果:b/2 ≤ a < 3b/2=""><=> 0 ≤ a-b/2 < b=""><=> 0 ≤ y <>
  • 2 如果:3b/2 ≤ a < 5b/2=""><=> b ≤ a-b/2 < 2b=""><=> 1 ≤ y <>

其中 y = (a-b/2)/b,因此 c 为:如果 y<0,则为 0,否则为="" 1+floor(y)。="" [而="">a 现在肯定是 < b/2="" 和="" ≥="">

所以你可以为 c 写一个表达式为:

x = (a+b/2)/b
y = (a-b/2)/b
c = (x≤0)*(ceiling(x) - 1 + (x is integer))
   +(y≥0)*(1 + floor(y))                

当然,接下来你会注意到 (ceiling(x)-1+(x is integer))floor(x+1)-1 相同是floor(x),而那个y其实就是x-1,所以(1+floor(y))=floor (x),关于条件句:
当x≤0时,不可能是(y≥0),所以c只是第一项即floor(x)
当 0 < x="">< 1="" 时,两个条件都不成立,所以="">c0,
当1≤x时,只有0≤y,所以c就是第二项,又是floor(x)。 所以 c = floor(x) 在所有情况下。

关于c++ - 将while循环变成数学方程式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/392375/

有关c++ - 将while循环变成数学方程式?的更多相关文章

  1. ruby - 树顶语法无限循环 - 2

    我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. ruby-on-rails - ruby 日期方程不返回预期的真值 - 2

    为什么以下不同?Time.now.end_of_day==Time.now.end_of_day-0.days#falseTime.now.end_of_day.to_s==Time.now.end_of_day-0.days.to_s#true 最佳答案 因为纳秒数不同:ruby-1.9.2-p180:014>(Time.now.end_of_day-0.days).nsec=>999999000ruby-1.9.2-p180:015>Time.now.end_of_day.nsec=>999999998

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby - Ruby 中的闭包和 for 循环 - 2

    我是Ruby的新手,有些闭包逻辑让我感到困惑。考虑这段代码:array=[]foriin(1..5)array[5,5,5,5,5]这对我来说很有意义,因为i被绑定(bind)在循环之外,所以每次循环都会捕获相同的变量。使用每个block可以解决这个问题对我来说也很有意义:array=[](1..5).each{|i|array[1,2,3,4,5]...因为现在每次通过时都单独声明i。但现在我迷路了:为什么我不能通过引入一个中间变量来修复它?array=[]foriin1..5j=iarray[5,5,5,5,5]因为j每次循环都是新的,我认为每次循环都会捕获不同的变量。例如,这绝对

  10. ruby - 从 Ruby : capturing the output while displaying the output? 运行 shell 命令 - 2

    我有一个问题。我想从另一个ruby​​脚本运行一个ruby​​脚本并捕获它的输出信息,同时让它也输出到屏幕。亚军#!/usr/bin/envrubyprint"Enteryourpassword:"password=gets.chompputs"Hereisyourpassword:#{password}"我运行的脚本文件:开始.rboutput=`runner`putsoutput.match(/Hereisyour(password:.*)/).captures[0].to_s正如您在此处看到的那样,存在问题。在start.rb的第一行,屏幕是空的。我在运行程序中看不到“输入您的密

随机推荐