C ++中缩小和截断之间的区别?
Difference between narrowing and truncation in C++?
我一直在浏览一本书(C++ 编程语言 Stroustrup 第 4 版)。
与初始化相关的部分中给出的示例如下:
void f(double d, int i)
{
int a{ d }; // error : possible truncation
char b{ i }; // error : possible narrowing
}
截断和缩小到底有什么区别?
double d=2.345;
int a = d; // a is 2 now, so the number 2.345 is truncated
至于int
到char
,char
有1个字节,而int
有4个字节(假设32位),所以你会"narrowing"变量i
.
可能只是英文:)你可以查字典,这样可能更清楚。
也许最好用一个例子来理解...
假设 d == 3.1415926
那么在您的代码中 a
将最终成为 3
。那就是截断。
另一方面,如果 i == 1000
则超出了 char
的范围。如果 char
是 unsigned
,该值将回绕,您将得到 1000%256
作为 b
的值。发生这种情况是因为 int
的范围比 char
更宽,因此这种转换称为缩小范围。
缩小转换基本上是任何可能导致信息丢失的转换。严格来说,narrowing conversion 是:
an implicit conversion
- from a floating-point type to an integer type, or
- from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or
- from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or
- from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type, or
- from a pointer type or a pointer-to-member type to bool.
请注意,这意味着您发布的两次转化都是缩小转化。 int a{ d };
是第一种,char b{ i };
是第四种。
只有在浮点型和整型之间转换时才会出现截断。一般指浮点数的小数部分丢失(source)。这意味着截断是缩小转换的子集。
What exactly is the difference between truncation and narrowing?
Truncation 将基于小数的值(例如 float
或 double
缩短为其具有额外精度的整数形式 int
删除小数点后的位(从 2-1 中相应的十进制形式)。
A double
也可以被截断为 float
,有可能发生溢出(取决于值的大小)并删除其二进制形式的一半精度位(因为 double 的精度是 float 的两倍,它们通常分别是 64 位和 32 位浮点数)。
对于 double
被截断为 float
的示例,考虑至少超过 23 个精度位(考虑浮点数的尾数)的东西,例如 PI 的值,关于 BenVoigt在评论中举了一个例子。
double给出的PI值为:
11.001001000011111101101010100010001000010110100011000
// 3.141592653589793116
注意这里有52个精度位(根据IEEE 754标准,从0到51),即小数点后的值。
对应的截断浮点值:
11.0010010000111111011011
// 3.1415927410125732422
请注意,相对于上述数字而言,PI 值不准确。这是由于在将值从 double
截断到 float
(只有 23 个精度位,从 0 到 22)时删除了尾部精度位,在这种情况下按顺序降低精度位.
在将浮点值转换为整数形式之后,您可以说它的行为类似于 floor
函数调用。
Narrowing 顾名思义就是缩短值,但与截断不同的是,它不限于将浮点值缩短为整数值。它也适用于其他转换,例如 long
到 int
、指针类型到布尔值和字符到整数(如您的示例)。
我一直在浏览一本书(C++ 编程语言 Stroustrup 第 4 版)。 与初始化相关的部分中给出的示例如下:
void f(double d, int i)
{
int a{ d }; // error : possible truncation
char b{ i }; // error : possible narrowing
}
截断和缩小到底有什么区别?
double d=2.345;
int a = d; // a is 2 now, so the number 2.345 is truncated
至于int
到char
,char
有1个字节,而int
有4个字节(假设32位),所以你会"narrowing"变量i
.
可能只是英文:)你可以查字典,这样可能更清楚。
也许最好用一个例子来理解...
假设 d == 3.1415926
那么在您的代码中 a
将最终成为 3
。那就是截断。
另一方面,如果 i == 1000
则超出了 char
的范围。如果 char
是 unsigned
,该值将回绕,您将得到 1000%256
作为 b
的值。发生这种情况是因为 int
的范围比 char
更宽,因此这种转换称为缩小范围。
缩小转换基本上是任何可能导致信息丢失的转换。严格来说,narrowing conversion 是:
an implicit conversion
- from a floating-point type to an integer type, or
- from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or
- from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or
- from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type, or
- from a pointer type or a pointer-to-member type to bool.
请注意,这意味着您发布的两次转化都是缩小转化。 int a{ d };
是第一种,char b{ i };
是第四种。
只有在浮点型和整型之间转换时才会出现截断。一般指浮点数的小数部分丢失(source)。这意味着截断是缩小转换的子集。
What exactly is the difference between truncation and narrowing?
Truncation 将基于小数的值(例如 float
或 double
缩短为其具有额外精度的整数形式 int
删除小数点后的位(从 2-1 中相应的十进制形式)。
A double
也可以被截断为 float
,有可能发生溢出(取决于值的大小)并删除其二进制形式的一半精度位(因为 double 的精度是 float 的两倍,它们通常分别是 64 位和 32 位浮点数)。
对于 double
被截断为 float
的示例,考虑至少超过 23 个精度位(考虑浮点数的尾数)的东西,例如 PI 的值,关于 BenVoigt在评论中举了一个例子。
double给出的PI值为:
11.001001000011111101101010100010001000010110100011000
// 3.141592653589793116
注意这里有52个精度位(根据IEEE 754标准,从0到51),即小数点后的值。
对应的截断浮点值:
11.0010010000111111011011
// 3.1415927410125732422
请注意,相对于上述数字而言,PI 值不准确。这是由于在将值从 double
截断到 float
(只有 23 个精度位,从 0 到 22)时删除了尾部精度位,在这种情况下按顺序降低精度位.
在将浮点值转换为整数形式之后,您可以说它的行为类似于 floor
函数调用。
Narrowing 顾名思义就是缩短值,但与截断不同的是,它不限于将浮点值缩短为整数值。它也适用于其他转换,例如 long
到 int
、指针类型到布尔值和字符到整数(如您的示例)。