从'size_t'转换为"常量双倍",可能会丢失数据

conversion from 'size_t' to 'const double', possible loss of data

本文关键字:数据 size 转换 常量      更新时间:2023-10-16

给定一个变量size_t idx,像double value = idx;这样的赋值在编译低于64位时会产生以下警告:

'initializing': conversion from 'size_t' to 'double', possible loss of data

这似乎与以下事实有关:size_t值在 8 位下编译时占用 64 个字节。但是,分配double value = static_cast<double>(idx)不会生成任何警告。有人可以向我解释为什么前一个作业不起作用而后者不起作用吗?

提前感谢!

当你这样做时

double value = idx;

编译器看着它,然后说:"嘿,idx可能无法适应value,让我们告诉程序员以防万一这是一个错误。 这就是您收到警告的原因。

当你这样做时

double value = static_cast<double>(idx)

编译器看着它,然后说:"哦,程序员在这里显式转换,这一定是他们想要的。这意味着它不会出现警告。

static_cast<double>是你告诉编译器你正在有意识地转换为double并意识到所有含义的方式。这意味着编译器不应该警告你这些风险,因为你已经明确告诉它你已经知道了这些风险。

在第一种情况下,如果您不使用static_cast,转换是合法的,但存在失去精度的风险。由于您可能没有注意到这种转换正在发生,因此警告您是有意义的。

这两个作业将"工作",事实上,做完全相同的事情!唯一的区别是,在第二种情况下,double value = static_cast<double>(idx),显式强制转换使编译器清楚地知道您"知道自己在做什么",并且您可能会在转换中丢失有效数字。

在第一种情况下,编译器只是警告您,您的转换可能会(无意中(导致数据丢失(在本例中为精度(。

这是一个警告,因为程序员可能没有意识到他们在分配期间丢失了位。

但是,如果你在那里有一个显式的强制转换,编译器会假设程序员知道他们在做什么,因为强制转换就在那里,而且非常在你的脸上。

64 位双精度仅使用 52 位来存储数字,其余用于存储符号(+-(和指数。(注:这是IEEE754实现,double的实现可能因其他语言标准而异(

一个unsigned int(又名size_t(使用所有的64位来存储数字,但没有空间留给指数,因此整数中没有浮点精度

,如size_t

因此,编译器告诉您,如果 64 位无符号整数大于 64 位double-type 的尾数可以存储的数量(即大于52 位(,则可能会导致数据丢失,并可能导致之后其余代码中的未定义行为。

static_cast<double>(idx)是程序员的断言,告诉编译器不要担心,你会记住上述预防措施。

来源:https://en.wikipedia.org/wiki/Double-precision_floating-point_format