【问题标题】:Negative zero int负零整数
【发布时间】:2020-10-01 11:30:14
【问题描述】:

我需要一个整数向量,我可以在其中区分 0 和 -0。 到目前为止,我已经想出了为这种特殊情况定义一个名为 zero_int 的新类的想法..

但是,现在我不能将普通整数和 zero_int 都推送到同一个向量中。 解决方案 std::variant 的大小为 8 字节,我需要为每个变量保留 4 的大小。 定义一个虚拟基类 my_int 并将 zero_int 设置为其派生类会将 zero_int 的大小增加到 32 字节...

我知道可以使用vector<void*> 之类的东西,但我不知道如何使用.. - 另外,指针向量中的指针指向的对象是否在内存中是连续的? - 这在这种情况下很重要。

对于如何解决此问题的任何建议,我将不胜感激

【问题讨论】:

  • 您的整数是否适合 24 位范围?如果是这样,您可以使用 float 而不会损失任何精度。
  • 呵呵,比我预想的还要短时间
  • 您应该创建一个新的整数类,其中包含一个 bool 表示符号和一个 unsigned int 表示值(hints herehere)并仅使用该类的实例填充您的向量。
  • @GiovanniCerretani “我需要为每个变量保留 4 的大小”
  • 大小可以通过位域轻松管理。

标签: c++ vector int variant negative-zero


【解决方案1】:

解决方案 std::variant 的大小为 8 字节,我需要为每个变量保留 4 的大小..

这是不可能的,除非您不介意丢失一个可能的非零 int 值。

这为我们带来了“显而易见”的解决方案:将 0 视为 -0,将每个正数视为自身减一。

    vec[i]:  -5 -4 -3 -2 -1  0 +1 +2 +3 +4 +5
my "value":  -5 -4 -3 -2 -1 -0 +0 +1 +2 +3 +4

(或者反过来做,这样可以让你在正负范围内对称;随你喜欢。)

让任何包装你的向量的类以适合你项目的任何方式处理这个“映射”。


指针向量中的指针指向的对象是否在内存中是连续的??

没有。

你不希望这里有更多的间接性。


有人会建议使用浮点,因为 IEEE 754 支持有符号零。但是,我认为在任何情况下切换到浮点来表示实数可能会带来比它解决的问题更多的问题。

【讨论】:

  • 使用此解决方案您会失去值 (2^31)-1,但这可能没问题?基本上需要小心溢出之类的......
  • 我很想走另一条路:将非负数视为其自然值,将负数视为其值加一。这样,正数都是正数,负数都是负数。它还消除了二进制补码范围内的不对称性。
  • 是的,或者那个。无论OP需要什么。但基本思想是一个简单的逐一映射,为负零添加一个槽。
  • 很好的解决方案,谢谢!,我放弃一个 int 值没有问题
  • 在我看来,“显而易见”的解决方案是放弃 -2^31 并使用补码。这为您提供了可表示值的对称范围,而此答案的可表示负值比正值多两个。
【解决方案2】:

我会考虑使用无符号类型并将最高位显式管理为符号位:

class my_int {
public:
    my_int(int v) { set(v); }
    explicit operator int() const { return get(); }
    bool is_negative() const { return value & sign_bit; }
private:
    const static unsigned sign_bit =
        1u << (std::numeric_limits<unsigned>::digits - 1);
    unsigned value;
    void set(int v) { value = v < 0 ? (-v) & sign_bit : v;
    }
    int get() const { return value & sign_bit ? -(value & ~sign_bit) : value; }
};

注意:已编写但未经测试。

【讨论】:

  • 更改一位不会改变值吗?
  • @Adam — 是的。这就是get() 屏蔽符号位的原因。
  • 目前无法编译。我的更改使其可以编译但无法正常工作,无论如何谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-25
  • 2013-07-06
  • 2012-08-24
  • 1970-01-01
  • 2017-06-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多