在双精度类型数组中使用 memset()

using memset() in double type array

本文关键字:memset 双精度 类型 数组      更新时间:2023-10-16

我想将所有索引值设置为双精度数组中的-1
这是我的代码:

double dp[505];
memset(dp,-1,sizeof(dp));
cout<<dp[0]<<"n";

但是当我尝试打印其值时,它显示出nan

nan是什么意思?是否可以在双数组中使用memset()

在C++中,你可以写:

double initValue = -1;
std::fill_n(dp, 505, initValue);

使用非双精度值设置双精度数组将不起作用。

memset对字节进行操作,而不是浮点数,并且所有字节设置为 -1 的double不等于 -1。我想你正在寻找std::fill

#include <algorithm>
std::fill(dp, dp + 505, -1.0);

或者,在第 C++11 中:

#include <algorithm>
#include <iterator>
std::fill(std::begin(dp), std::end(dp), -1.0);

您已将数组的每个元素设置为用字节0xFF填充(即-1char表示形式(。

没有浮点数由一系列0xFF字节表示,因此在打印double时,您会看到NaN(即"不是数字"(。这与memset将字节设置为零形成鲜明对比,后者是合法的,因为 0 字节的字符串是值为零的double。请参阅在双精度数组上使用 memset(,0,( 是否合法?。

如果您打算将每个条目设置为 -1.0(即双精度(,则在 C++ 中使用 std::fillstd::fill_n 或在 C 中使用循环,例如

int n;
for (n = 0 ; n < 505 ; n++)
    dp[n] = -1.0;

memset 的手册页:

memset() 函数用常量字节 c 填充 s 指向的内存区域的前 n 个字节。

问题是你想用常量-1.0填充一个double数组,但sizeof(double) > 1 memset实际上填充了恰好最终成为 NaN 的垃圾。

如果您使用的是C++,则std::fill函数是您的朋友。 实际上,由于您是第一次写入数组,因此std::uninitialized_fill是正确的。 虽然对于内置double类型应该没有区别,但精确总是好的。

constexpr std::size_t length = 505;
double values[length];
std::uninitialized_fill(values, values + length, -1.0);

memset设置字节,因此您可以获得double值,其中每个字节都-1

相反,在C++使用std::vector,然后写

vector<double> dp( 505, -1.0 );

就是这么简单。


如果dp是全局向量,并且您需要将其设置为多次-1,那么您可以简单地执行以下操作:

dp = vector<double>( dp.size(), -1.0 );

但是,使用非const全局变量通常不是一个好主意。


或者,可以使用std::fill,或者只是一个循环,或者几乎任何仍然将double值视为double值的技术。但是,出于许多其他原因,std::vector也比大大简化填充任务更可取。特别是std::vector可以调整大小,它负责复制,并自动执行内存管理,正确执行该部分并且对您透明。

nan 表示不是一个数字。

不明白为什么它不起作用。也许是因为没有设置精度:(cout.precision(15(;)

检查这个:如何使用 cout 以全精度打印双精度值?

但我完全不确定它会起作用:o我检查了Memset源代码,没有负面:D的问题

但这可能是双打的问题:

memset(dst0, c0, length) void *dst0;
register int c0;
register size_t length;

你有没有尝试过用Werror标志编译?

虽然已经给出了你的问题的答案,但我只是想让你注意到 sizeof(dp)输出用于在内存中对变量进行编码的字节数。

在您的情况下,dp 是指向双精度的指针。然后,它将等于指针 (4( 的大小,无论是否分配了内存。sizeof(*dp( 将输出双精度 (8( 的大小。为了使用长度