【问题标题】:Extracting hours, minutes and seconds from binary encoding从二进制编码中提取小时、分钟和秒
【发布时间】:2018-07-29 20:27:33
【问题描述】:

我写了一个程序来解决下面的练习。我的小时和分钟是正确的,但我的秒数是错误的。

为了节省磁盘空间目录项中的时间字段为2 字节长。占小时的不同位的分布, 分和秒如下:

15 14 13 12 11|10  9  8  7  6  5| 4  3  2  1  0
 H  H  H  H  H| M  M  M  M  M  M| S  S  S  S  S

编写一个 C++ 程序,它接受输入的两字节时间条目和 使用合适的适当分隔小时、分钟和秒 位运算符。

#include<iostream>
using namespace std;
int main()
{
    unsigned int hours, mins, secs;
    unsigned int time;
    cout << "enter time ";
    cin >> time;
    hours = (time >> 11);
    mins = ((time << 5) >> 10); 
    secs = ((time << 11) >> 11);
    cout << hours << "  " << mins << "  " << secs << endl;
    return 0;
}

为了获得分钟,我将输入向左移动 5 个位置,希望消除所有 H 位,然后向右移动 10 个位置以消除所有 S 位并获得 @ 987654325@ 最右边的位。

几秒钟也是如此。

但是,如果我输入 445,我希望结果是 13 分 29 秒,但程序会输出 0 13 445

为什么小时和分钟显示正确,而秒却不正确?

【问题讨论】:

  • “以下问题”——哪个问题?
  • "cannot get my seconds right" – 你认为什么是“正确的”?你会得到什么?
  • 您能否举例说明如何使用它:输入的内容、期望的输出内容以及实际得到的内容?
  • ((time&lt;&lt;11)&gt;&gt;11)&amp;9 是的,这似乎不对。
  • 如果用户正在输入时间,您可能需要比位移更小心。至少对我来说,尚不清楚时间的格式。没有什么可以确保他们只输入数字、十六进制、十进制、24 或 12 小时制、上午/下午等。

标签: c++ bit-manipulation bit masking


【解决方案1】:
secs = time & 0x1F; // This should give the 5 bits you're expecting for seconds.

【讨论】:

  • 这对给定问题来说是一个更好的解决方案。 (但他不会明白为什么他的实现会失败......)
【解决方案2】:

您假设 unsigned int 的大小是 16 位,但在现在的机器上它通常实现为 32 位整数。

如果您将 uint16_t 用于可变时间,它应该可以工作。

要使用 uint16_t,请包含头文件 stdint.h。

#include <iostream>
#include <stdint.h>

using namespace std;

int main()
{
    uint16_t hours, mins, secs;
    uint16_t time = 445;
    hours = (time >> 11);
    mins = ((time << 5) >> 10);
    secs = (time << 11);
    secs >>= 11;
    cout << hours << "  " << mins << "  " << secs << endl;
    return 0;
}

(在 QT 5.5 上测试)

【讨论】:

  • 你应该测试你的答案。这是不正确的。 ideone.com/Dd0AhH
  • 我用 QtCreator 在真机上测试过它,它可以工作。
  • 您的示例适用于秒值,但在您刚刚建议 op replace int with uint16_t 之前没有。你知道为什么吗?使用 0xffff 尝试您的示例并观察分钟值。
  • 还要考虑secs = (uint16_t(time &lt;&lt; 11) &gt;&gt; 11); 也可以。没有强制转换或将其分配回 uint16_t 的临时类型是什么?您正在做的事情使这个问题和答案比看起来更有趣。
【解决方案3】:

您应该将与您正在查看的时间部分不对应的位归零。我将使用二进制文字(在 C++14 中可用),但注释等效的十六进制文字。

struct time {
    time(unsigned = 0); // also default constructs
    unsigned hours;
    unsigned mins;
    unsigned secs;
}

time::time(unsigned packed) : 
    hours((packed & 0b1111100000000000) >> 11), // 0xF800
    mins ((packed & 0b0000011111100000) >> 5 ), // 0x07E0
    secs ((packed & 0b0000000000011111)      )  // 0x001F
 { }

#include<iostream>

std::ostream& operator<< (std::ostream& os, time t) {
    return os << t.hours << "  " << t.mins << "  " << t.secs;
}

int main()
{
    time t(445);
    std::cout << t << std::endl;
    return 0;
}

【讨论】:

    【解决方案4】:

    给出的任务是不可能的,因为分钟秒都需要6位。您已经为秒分配了 5 位。

    • 2^5=32
    • 2^6=64

    使用这种方案,需要 17 位来表示时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-17
      • 2022-01-17
      • 1970-01-01
      • 2012-06-08
      • 2020-11-21
      • 1970-01-01
      • 2011-07-26
      相关资源
      最近更新 更多