Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将一位换成两位_C++_Double_Bit - Fatal编程技术网

C++ 将一位换成两位

C++ 将一位换成两位,c++,double,bit,C++,Double,Bit,我尝试在双精度中更改一位,例如: 双x:-1.500912597,即: 二进制:10111111111 000 00000011 10111100 11101101101 01100100 01001111 10010011 更改基础二进制代码中的一位(例如,位16),以便: 二进制:101111111110000000011 10111100 111011101 01100100 01001111 10010011 双x:-1.5634125969999903 有什么C++代码我可以用这个吗?

我尝试在双精度中更改一位,例如:

双x:
-1.500912597
,即:

二进制:
10111111111 000 00000011 10111100 11101101101 01100100 01001111 10010011

更改基础二进制代码中的一位(例如,位16),以便:

二进制:
101111111110000000011 10111100 111011101 01100100 01001111 10010011

双x:
-1.5634125969999903

有什么C++代码我可以用这个吗?< /p> <代码>

#include <ieee754.h>

ieee754_double d = {-1.500912597};
d.ieee.mantissa1 |= 1u << 16; // set bit 16 of mantissa
double x = d.d;
ieee754_双d={-1.500912597};
d、 ieee.尾数1 |=1u唯一可移植的方法是使用
memcpy
(是的,我知道你在想什么,不,这不是低效的)

请注意,此解决方案不考虑字节顺序。你也需要考虑到这一点,以确保严格的便携性

#include <cstdlib>
#include <cstring>
#include <utility>
#include <iostream>

// only compile this function if Integer is the same size as a double
template<class Integer, std::enable_if_t<sizeof(Integer) == sizeof(double)>* = nullptr>
double or_bits(double input, Integer bits)
{
  Integer copy;

  // convert the double to a bit representation in the integer 
  std::memcpy(&copy, &input, sizeof(input));
  // perform the bitwise op
  copy |= bits;
  // convert the bits back to a double
  std::memcpy(&input, &copy, sizeof(copy));
  // return the double
  return input;
}

int main()
{
  double d = 1.0;
  d = or_bits(d, 0x10ul);
  std::cout << d << std::endl;
}
#包括
#包括
#包括
#包括
//仅当Integer与double大小相同时才编译此函数
模板
双位或_位(双输入,整数位)
{
整数拷贝;
//将双精度转换为整数中的位表示形式
std::memcpy(©,&input,sizeof(input));
//执行按位运算
复制|=位;
//将位转换回双精度
std::memcpy(&input,©,sizeof(copy));
//还双倍
返回输入;
}
int main()
{
双d=1.0;
d=或_位(d,0x10ul);

位操作有无限的可能性。所以你应该练习,但我会给你一些例子

以下代码将仅“设置”x的第3位(其中第0位为最低有效位):

以下代码将仅“重置”位3:

#define RESET_BIT3 (0xFFFFFFFFFFFFFFF7)
x &= RESET_BIT3;
你可以做的另一件事是建立这样的联盟:

typedef union
{
    struct
    {
        unsigned BIT0:1;
        unsigned BIT1:1;
        unsigned BIT2:1;
        unsigned BIT3:1;
        unsigned BIT4:1;
        unsigned BIT5:1;
        unsigned BIT6:1;
        unsigned BIT7:1;
        unsigned BIT8:1;
        unsigned BIT9:1;
        unsigned BIT10:1;
        unsigned BIT11:1;
        unsigned BIT12:1;
        unsigned BIT13:1;
        unsigned BIT14:1;
        unsigned BIT15:1;
    };
    struct
    {
        unsigned BYTE0:8;
        unsigned BYTE1:8;
    };
    struct
    {
        unsigned ALL:16;
    };
}two_bytes;
你能做的是:

two_bytes var;

var.ALL = 0; // clear all bits
var.BYTE1 = 0xFF; // make all bits of most significant byte 1
var.BIT7 = 1; // set only bit 7 
或者您可以再次转换为按位运算符:

#define SET_BIT3 (0x08)
var.ALL |= SET_BIT3;

是的,有一些C++代码可以使用。你的谷歌关键词是“联合”。@标准的C++ + @ Jens bitwise运算符不能用于<代码>双 @ JoachimPileborg。可以使用<代码>无符号char */Cube >(或<代码> MeMCPy < /C>)编写该位。这并不违反严格的别名…问题是系统可能会使用各种字节顺序(如果我们假设ieee754正在使用的话)这是可能的,但您需要通过使用指针将变量视为
无符号字符的数组来绕过。尽管如此,在字节顺序和实际使用的浮点格式(如@M.M所述)方面存在其他问题。这也会使代码难以理解和维护,这一点更为重要(IMO)<代码> IEEE75 4.h < /COD>不是ISO C++的一部分,最好是添加到您的答案中解释使用什么包来使用您的代码,即使IEEE75 4.h不是ISO C++的一部分,我认为访问这种方式比其他选项更干净。在Visual Studio中使用<代码> GLYBC首标包是可能的吗?我一直在尝试。要查找如何,但我说的是正确的吗?在许多平台上,代码>未签名的/CODE >是4字节宽。使用一个可移植的类型,如 UTI1616T 。标准是C++中未定义的行为。Bitfield布局是定义的实现,因此这也会使你很难知道你得到正确的字节。@ MaximEgorushkin是的,但这只是一种示例类型,有时在嵌入式平台中,我更喜欢灵活性而不是可移植性。这是制造商在其代码中定义微控制器寄存器的常用方式。据我所知,
memcpy
不是唯一的可移植方式。使用
char*
手动更改位也有很好的定义。我临时复制并粘贴您的代码(到VS2015中)但我有几个错误:。这是因为我使用的是另一个编译器吗?@Milan我想这是因为该系统上的
无符号long
double
的大小不同。你需要从大小中推断出正确的类型。@RichardHodges确实,在我的系统上,无符号long=4字节,而double=8字节,所以我猜不会编译函数,然后将0x10ul更改为0x10ull
two_bytes var;

var.ALL = 0; // clear all bits
var.BYTE1 = 0xFF; // make all bits of most significant byte 1
var.BIT7 = 1; // set only bit 7 
#define SET_BIT3 (0x08)
var.ALL |= SET_BIT3;