パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

Zuneとgigabeatが閏年の処理の問題でフリーズ」記事へのコメント

  • by Anonymous Coward
    Freescaleの参照ドライバがバグっていた模様です。
    閏年の判断が間違ってたわけじゃなくて、1980年1月1日からの日数を閏年を考慮して年初からの日数に直すところで無限ループに入っていたという…
    http://www.zuneboards.com/forums/zune-news/38143-cause-zune-30-leapyea... [zuneboards.com]
    • by Anonymous Coward
      素直に書けば、これだけのこと?

      year = ORIGINYEAR; /* = 1980 */
       
      while (days > (IsLeapYear(year) ? 366 : 365))
      {
        days -= IsLeapYear(year) ? 366 : 365;
        year += 1;
      }
      • by Anonymous Coward
        教科書的に書けばこんな感じ。

        year = ORIGINYEAR; /* = 1980 */
        year_days = IsLeapYear(year) ? 366 : 365;
        while (days > year_days)
        {
            days -= year_days;
            year += 1;
            year_days = IsLeapYear(year) ? 366 : 365;
        }
        • Re: (スコア:1, 参考になる)

          by Anonymous Coward
          両方とも、「IsLeapYear(year) ? 366 : 365;」が複数箇所に記述されてるのは駄目だろう。
          この程度なら余裕で見通せるだろうが、基本的に同一の記述が複数にあると潜在バグの元になる。
          過去の遺産的なつぎはぎ修正のプログラムは、たいていこんなものが散見されて、コピペミスと思われるバグがあったりするよ。
          • by Anonymous Coward
            つまり、実用的に書くとこんな感じ?

            year = ORIGINYEAR; /* = 1980 */
            while (1)
            {
                if (IsLeapYear(year))
                {
                    if (days <= 366) break;
                    days -= 366;
                }
                else
                {
                    if (days <= 365) break;
                    days -= 365;
                }
                year += 1;
            }
            • by Anonymous Coward
              この場合はforで書いたほうが読みやすいよ。

              for (year = ORIGINYEAR; ; year++)
              {
                  if (IsLeapYear(year))
                  {
                      if (days <= 366) break;
                      days -= 366;
                  }
                  else
                  {
                      if (days <= 365) break;
                      days -= 365;
                  }
              }
              • Re: (スコア:1, 興味深い)

                by Anonymous Coward
                これ、実用的なの?ifの中身を同じアルゴリズムにするのと、ローカル変数を一つ増やすのとの差でしょ?

                for (year = ORIGINYEAR;; year++) {
                  year_days = IsLeapYear(year)? 366 : 365;
                  if (days <= year_days)
                    break;
                  days -= year_days;
                }
                おそらく、組み込み系にとっての、という意味だと思うが…。
              • by Anonymous Coward
                for文もwhile文も使わない経過日数の計算アルゴリズム [ufcpp.net]もありますね。
                ドキュメンテーションをしっかりしておく必要はありますが。。
              • by Anonymous Coward on 2009年01月02日 22時43分 (#1484512)
                days=`date +%j`

                ってのはドライバということだとだめなんでしょうけど、
                なぜに1980年からの通算日数から年内日数なのでしょう? RTCにはBCDで
                月日が格納されるのがほとんどだと思うのですが。

                epochが1980年?とググったらarcプロセッサのシステムで
                採用しているみたいですね。
                親コメント
              • by Anonymous Coward
                ソフトウェアで年月日に変換すればいいのだから、クロックは単なる2進カウンタで実装したほうが、回路のコストが浮きますよ。
                微々たるものですが、ソフトウェアで十分なものをハードウェアでやるのは、どーかと思います。

皆さんもソースを読むときに、行と行の間を読むような気持ちで見てほしい -- あるハッカー

処理中...