从 'size_t' 转换为 'const double',可能会丢失数据
conversion from 'size_t' to 'const double', possible loss of data
给定一个变量 size_t idx
,在 64 位下编译时,像 double value = idx;
这样的赋值会产生以下警告:
'initializing': conversion from 'size_t' to 'double', possible loss of data
这似乎与在64位下编译时size_t
值占用8个字节有关。但是,赋值 double value = static_cast<double>(idx)
不会产生任何警告。有人可以向我解释为什么前一个作业不起作用而后者起作用吗?
提前致谢!
这是一个警告,因为程序员可能没有意识到他们在赋值过程中丢失了位。
但是,如果您在那里进行了显式转换,编译器会假定程序员知道他们在做什么,因为转换就在那里,而且就在您的面前。
static_cast<double>
是您告诉编译器您正在有意识地转换为 double
并且了解所有含义的方式。这意味着编译器不应该警告您这些风险,因为您已经明确告诉它您已经知道这些风险。
在第一种情况下,您不使用 static_cast
,转换是合法的,但存在丢失精度的风险。由于您可能没有注意到这种转换正在发生,因此向您发出警告很有意义。
两项作业都 'work',而且实际上做的是完全一样的事情!唯一的区别是,在第二种情况下,double value = static_cast<double>(idx)
,你的 explicit 转换让编译器清楚地知道你 "know what you're doing" 并且你可能会丢失有效数字转换。
在第一种情况下,编译器只是警告您您的转换可能(无意中)导致数据丢失(或精度,在这种情况下)。
当你这样做时
double value = idx;
编译器查看它并运行:"Hey, idx
might not be able to fit in value
, lets tell the programmer in case it was a mistake."。这就是您收到警告的原因。
当你这样做时
double value = static_cast<double>(idx)
编译器查看它并运行:"Oh, the programmer is explicitly casting here, this must be what they want."。这意味着它不会出现警告。
64 位双精度数仅使用 52 位存储数字,其余部分用于存储符号(+
或 -
)和指数。 (注意:这是IEEE754的实现,double
的实现在其他语言标准中可能有所不同)
unsigned int
(a.k.a size_t
) 使用所有 64 位来存储数字,但没有为指数留出空间,因此没有 浮点整数精度,如size_t
因此,编译器告诉您,如果您的 64 位无符号整数大于 64 位 double
类型的尾数可以存储的数量(即 更大 比 52 位 ),它可能会导致数据丢失,并可能导致代码的其余部分出现未定义行为。
做static_cast<double>(idx)
是程序员告诉编译器不要担心的断言,您会牢记上述预防措施。
来源:https://en.wikipedia.org/wiki/Double-precision_floating-point_format
给定一个变量 size_t idx
,在 64 位下编译时,像 double value = idx;
这样的赋值会产生以下警告:
'initializing': conversion from 'size_t' to 'double', possible loss of data
这似乎与在64位下编译时size_t
值占用8个字节有关。但是,赋值 double value = static_cast<double>(idx)
不会产生任何警告。有人可以向我解释为什么前一个作业不起作用而后者起作用吗?
提前致谢!
这是一个警告,因为程序员可能没有意识到他们在赋值过程中丢失了位。
但是,如果您在那里进行了显式转换,编译器会假定程序员知道他们在做什么,因为转换就在那里,而且就在您的面前。
static_cast<double>
是您告诉编译器您正在有意识地转换为 double
并且了解所有含义的方式。这意味着编译器不应该警告您这些风险,因为您已经明确告诉它您已经知道这些风险。
在第一种情况下,您不使用 static_cast
,转换是合法的,但存在丢失精度的风险。由于您可能没有注意到这种转换正在发生,因此向您发出警告很有意义。
两项作业都 'work',而且实际上做的是完全一样的事情!唯一的区别是,在第二种情况下,double value = static_cast<double>(idx)
,你的 explicit 转换让编译器清楚地知道你 "know what you're doing" 并且你可能会丢失有效数字转换。
在第一种情况下,编译器只是警告您您的转换可能(无意中)导致数据丢失(或精度,在这种情况下)。
当你这样做时
double value = idx;
编译器查看它并运行:"Hey, idx
might not be able to fit in value
, lets tell the programmer in case it was a mistake."。这就是您收到警告的原因。
当你这样做时
double value = static_cast<double>(idx)
编译器查看它并运行:"Oh, the programmer is explicitly casting here, this must be what they want."。这意味着它不会出现警告。
64 位双精度数仅使用 52 位存储数字,其余部分用于存储符号(+
或 -
)和指数。 (注意:这是IEEE754的实现,double
的实现在其他语言标准中可能有所不同)
unsigned int
(a.k.a size_t
) 使用所有 64 位来存储数字,但没有为指数留出空间,因此没有 浮点整数精度,如size_t
因此,编译器告诉您,如果您的 64 位无符号整数大于 64 位 double
类型的尾数可以存储的数量(即 更大 比 52 位 ),它可能会导致数据丢失,并可能导致代码的其余部分出现未定义行为。
做static_cast<double>(idx)
是程序员告诉编译器不要担心的断言,您会牢记上述预防措施。
来源:https://en.wikipedia.org/wiki/Double-precision_floating-point_format