JavaScript表达式评估错误

时间:2016-03-18 01:33:58

标签: javascript algorithm date math

我正在使用Zeller的同意来预测特定日期的星期几。该算法将从0...6返回一个值。 0表示星期日,1表示星期一,2表示星期二等。算法是这样的:

Day = ((26M-2)/10 + D + Y + Y/4 + C/4 + 5C) MOD 7

算法中有一部分陈述

IF Month < 3 THEN
    Year = Year - 1
    Month = Month + 10
ELSE
    Month = Month - 2
END IF;

D是哪一天,Y是年份的最后两位数,M是月份,C是前两个世纪年度数字。

出于某种原因,当我将其插入javascript时,我得到的结果不正确。采取日期2/15/16。这个日期发生在星期一。这是我的算法代码:

(Math.floor((26 * monthVal) - 2 / 10) + dayVal + yearVal + Math.floor(yearVal / 4) + Math.floor(centuryVal / 4) + (5 * centuryVal)) % 7

我输入了调试语句,以确保monthValdayValyearVal等都正确无误。此表达式应评估为1,但由于某种原因,它的计算结果为0。当我分解它时,我得到了正确的结果。所以:

上面给出的日期的

Math.floor(((26 * monthVal) - 2) / 10)出现在Math.floor(((26 * 12) - 2) / 10) = 31

dayVal = 15yearVal = 15centuryVal = 20Math.floor(yearVal / 4) = 3Math.floor(centuryVal / 4) = 5(5 * centuryVal) = 100

如果我们把所有这些放在一起,我们得到

(31 + 15 + 15 + 3 + 5 + 100) % 7 = 1

当我使用上面直接输入的数字将其插入计算机时,它会得到正确的答案。但是,当我使用变量名称并将它们全部放在一起时,就像我上面的11-12行一样,同样的表达式出现在0,我不知道为什么。它怎么会给我错误的答案,即使我手工工作,我得到了正确的答案?我错过了与操作优先级有关的内容吗?

2 个答案:

答案 0 :(得分:1)

看起来你的第一个表达看起来很好(至少在今天),如果你把一个括号放在这个位置:

(Math.floor((26 * monthVal - 2) / 10) + dayVal + yearVal + Math.floor(yearVal / 4) + Math.floor(centuryVal / 4) + (5 * centuryVal)) % 7

注意2之后的括号,而不是之前。

https://jsfiddle.net/7hjw63d3/

答案 1 :(得分:0)

实施整个算法并更正:

Math.floor((26 * monthVal) - 2 / 10)

Math.floor((26 * monthVal - 2) / 10)

给出:

&#13;
&#13;
// Very simple parser of dates in d/m/y format
function parseDMY(s) {
  var b = s.split(/\D/);
  return new Date(b[2], b[1]-1, b[0]);
}
  
['15/2/2016','16/2/2016','17/2/2016','18/2/2016','19/2/2016',
 '20/2/2016','21/2/2016','22/2/2016','23/2/2016','24/2/2016',
 '25/2/2016','26/2/2016','27/2/2016','28/2/2016','29/2/2016',
 '1/3/2016','2/3/2016','3/3/2016','4/3/2016','5/3/2016',
 '1/1/2016','30/6/2016','23/10/2016','1/1/2000'].forEach(function(s) {
  var d = parseDMY(s);
  var b = s.split(/\D/);
  var day = +b[0], 
      month = b[1] - 2,
      cent = b[2]/100|0,
      yr = b[2]%100;
  if (month < 1) {
    month += 12;
    yr -= 1;
  } 
  document.write(d + ' : ' + 
    ((Math.floor((26 * month - 2) / 10) + day + yr + Math.floor(yr / 4) + Math.floor(cent / 4) + (5 * cent)) % 7)
    + '<br>'
  );
})  
&#13;
&#13;
&#13;

此外,OP中的测试值似乎不正确,年份应为16,而不是15。