1

我想为这样的变量赋值:

double var = 0xFFFFFFFF;

结果var得到分配的值 65535.0。由于编译器假定目标系统为 64 位,因此数字文字(即所有相应的 32 位)被解释为有效位和精度位。但是,由于0xFFFF FFFF只是位模式的一种表示法,没有任何关于表示的提示,因此它可能会被完全不同地解释为浮点值。因此,我想知道是否有办法操纵对值的这种固定解释。换句话说,给出关于所需表示的提示。(也许有人也可以指出我参与定义这种隐含解释的标准)。

到目前为止,我系统上的默认精度解释似乎是

(int)0xFFFFFFFF x 10 0

在此处输入图像描述 只有分数字段被填充1

所以也许(这里:对于 16 位交叉编译)我希望它是一种不同的表示形式,例如:

(int)0xFFFFFF x 10 (int)0xFF

(暂时忽略符号位)。

因此我的问题是:如何强制对十六进制文字符号进行自定义双重解释?


1 即使我的十六进制文字是0xFFFF FFFF FFFF FFFF该值仅解释为小数部分 - 很明显,位应该用于指数和符号字段。但似乎文字被切断了。

4

3 回答 3

3

“我想知道是否有办法操纵这种解释。”

是的,您可以使用reinterpret_cast<double&>通孔地址来强制从内存中的某个位模式进行类型(重新)解释。

“因此我的问题是:如何强制对十六进制表示法进行双重解释?”

您还可以使用联合,使其更清晰:

union uint64_2_double {
    uint64_t bits;
    double dValue;
};

uint64_2_double x;
x.bits = 0x000000000000FFFF;

std::cout << x.dValue << std::endl;
于 2015-06-25T19:53:12.563 回答
3

似乎没有直接的方法来初始化double具有十六进制模式的变量,c 样式转换等效于 C++ static_cast,并且reinterpret_cast会抱怨它无法执行转换。我会给你两种选择,一种是简单的解决方案,但不会直接初始化变量,另一种是复杂的。您可以执行以下操作:

double var; *reinterpret_cast<long *>(&var) = 0xFFFF;

注意:请注意,我希望您希望初始化 的所有 64 位double,您的常量 0xFFFF 似乎很小,它给出 3.23786e-319

以 0x 开头的文字值是 unsigned int 类型的十六进制数。您应该使用后缀 ul 使其成为 unsigned long 的文字,这在大多数体系结构中意味着 64 位无符号;或者,#include <stdint.h>例如uint64_t(0xABCDFE13)

现在来看复杂的东西:在旧的 C++ 中,您可以编写一个将整数常量转换为双精度的函数,但它不会是constexpr.

constexpr你不能做的功能中reinterpret_cast。然后,使 constexpr 转换器加倍的唯一选择是在中间使用联合,例如:

struct longOrDouble {
    union {
        unsigned long asLong;
        double asDouble;
    };
    constexpr longOrDouble(unsigned long v) noexcept: asLong(v) {}
};

constexpr double toDouble(long v) { return longOrDouble(v).asDouble; }

这有点复杂,但这回答了你的问题。现在,您可以编写: double var = toDouble(0xFFFF) 这会将给定的二进制模式插入到双精度中。

用于union写入一个成员并从另一个成员读取是 C++ 中未定义的行为,这里有一个很好的问题和很好的答案: Accessing inactive union member and undefined behavior?

于 2015-06-25T20:09:33.657 回答
3

C++ 没有为 指定内存中的表示double,而且,它甚至没有指定整数类型的内存中表示(并且在具有不同结尾的系统上它确实可能不同)。因此,如果您想将 bytes 解释为 a 0xFF,您可以执行以下操作:0xFFdouble

uint8_t bytes[sizeof(double)] = {0xFF, 0xFF};
double var;
memcpy(&var, bytes, sizeof(double));

请注意reinterpret_cast,严格来说,使用 unions 或 ing 指针是未定义的行为,尽管在实践中也有效。

于 2015-06-25T20:18:09.210 回答