什么时候转换在C ++中改变一个值的位? [英] When does casting change a value's bits in C++?

查看:124
本文介绍了什么时候转换在C ++中改变一个值的位?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C ++ unsigned int ,它实际上是存储一个有符号的值。我想将此变量转换为 signed int ,以便无符号和有符号值具有相同的二进制值。

  unsigned int lUnsigned = 0x80000001; 
int lSigned1 =(int)lUnsigned; // ligned == 0x80000001?
int lSigned2 = static_cast< int>(lUnsigned); // ligned == 0x80000001?
int lSigned3 = reinterpret_cast< int>(lUnsigned); //编译器不喜欢这个

当转换改变C ++中的一个变量的位例如,我知道从 int 转换为 float 会更改位,因为 int 是二进制补码, float 是浮点型。但是其他情况呢?我不清楚C ++中的规则。



在C99规范的6.3.1.3节中,说从无符号到有符号整数的转换是编译器 -

解决方案

类型转换




  • 保留概念值(必须更改bitpattern


  • <




唯一的C ++强制转换总是保持bitpattern为 const_cast



A reinterpret_cast 是,正如其名字所暗示的,旨在保持bitpattern,只是重新解释它。但是标准允许实现非常多的空间如何实现 reinterpret_cast 。在某些情况下, reinterpret_cast 可能会更改bitpattern。



A dynamic_cast 通常改变bitpattern和value,因为它通常深入一个对象,并返回一个指向/请求类型的子对象的引用。



A static_cast 可以改变整数和指针的位模式, ,几乎所有现存的计算机都使用有符号整数(称为二的补码) $ c> static_cast 不会更改bitpattern。关于指针,足以说,例如,当一个基类是非多态的,并且一个派生类是多态的,使用 static_cast 从指针到派生指针到base,反之亦然,可以改变bitpattern(正如你在比较 void * 指针时可以看到的)。现在,整数...



使用 n 值位,无符号整数类型具有2 ^在范围0到2 ^ n

-1(包括)。



C ++标准保证类型的任何结果<通过添加或减去2 ^ n的合适倍数

,将包装到该范围。

实际上,这是C标准描述的方式; C ++标准只是说操作是 2 ^ n ,这意味着相同。



>二进制补码形式有符号值 - x 具有与无符号值 x + 2 ^ n相同的位模式。也就是说,与C ++标准相同的位模式保证通过将 x 转换为相同大小的无符号类型。这是二进制补码形式的简单基础,这正是您寻求的保证。 : - )



几乎所有现存的电脑都使用二进制补码形式。



保证您的示例不变的bitpattern。


I have a C++ unsigned int which is actually storing a signed value. I want to cast this variable to a signed int, so that the unsigned and signed values have the same binary value.

unsigned int lUnsigned = 0x80000001;
int lSigned1 = (int)lUnsigned;                   // Does lSigned == 0x80000001?
int lSigned2 = static_cast<int>(lUnsigned);      // Does lSigned == 0x80000001?
int lSigned3 = reinterpret_cast<int>(lUnsigned); // Compiler didn't like this

When do casts change the bits of a variable in C++? For example, I know that casting from an int to a float will change the bits because int is twos-complement and float is floating-point. But what about other scenarios? I am not clear on the rules for this in C++.

In section 6.3.1.3 of the C99 spec it says that casting from an unsigned to a signed integer is compiler-defined!

解决方案

A type conversion can

  • keep the conceptual value (the bitpattern may have to be changed), or

  • keep the bitpattern (the conceptual value may have to be changed).

The only C++ cast that guaranteed always keeps the bitpattern is const_cast.

A reinterpret_cast is, as its name suggests, intended to keep the bitpattern and simply reinterpret it. But the standard allows an implementation very much leeway in how to implement reinterpret_cast. In some case a reinterpret_cast may change the bitpattern.

A dynamic_cast generally changes both bitpattern and value, since it generally delves into an object and returns a pointer/reference to a sub-object of requested type.

A static_cast may change the bitpattern both for integers and pointers, but, nearly all extant computers use a representation of signed integers (called two's complement) where static_cast will not change the bitpattern. Regarding pointers, suffice it to say that, for example, when a base class is non-polymorphic and a derived class is polymorphic, using static_cast to go from pointer to derived to pointer to base, or vice versa, may change the bitpattern (as you can see when comparing the void* pointers). Now, integers...

With n value bits, an unsigned integer type has 2^n values, in the range 0 through 2^n-1 (inclusive).

The C++ standard guarantees that any result of the type is wrapped into that range by adding or subtracting a suitable multiple of 2^n.

Actually that's how the C standard describes it; the C++ standard just says that operations are modulo 2^n, which means the same.

With two's complement form a signed value -x has the same bitpattern as the unsigned value -x+2^n. That is, the same bitpattern as the C++ standard guarantees that you get by converting -x to unsigned type of the same size. That's the simple basics of two's complement form, that it is precisely the guarantee that you're seeking. :-)

And nearly all extant computers use two's complement form.

Hence, in practice you're guaranteed an unchanged bitpattern for your examples.

这篇关于什么时候转换在C ++中改变一个值的位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆