memset 将一些元素设置为 *almost* 零或 nan
memset sets some elements to *almost* zero or nan
我有行 memset(C, 0, N*M);
,其中 C 是双精度矩阵。 (我正在使用 WSL。)
但是,如果我查看 gdb,矩阵中的某些元素设置为 -nan(0xffffffffffff8)
,而其他元素设置为 9.0096750001652956e-314
。
第一个没有给出任何错误,但是 +=
似乎没有改变任何东西(或者至少似乎没有让 nan 的东西消失),而第二个是如果元素未更改或仅具有 += 0
,则会出现问题,因为比较 if (0 == C[i][j])
会失败。
如果我手动将值设置为 0,则根本不会出现这些问题。
这是 WSL 的事情,还是 memset
有什么我不明白的地方?
M*N
是 items 的数量(双倍)但是 memset
期望 bytes 的数量.对于数组 double C[M][N]
,您需要执行 memset(C, 0, sizeof(C));
.
您没有完全初始化矩阵:memset()
需要一些字节。假设矩阵布局是线性的,无论是一维还是二维,您应该清除 sizeof(double) * N * M
字节。
如果您的矩阵定义为二维数组,您可以这样写:
#define N 10
#define M 20
double C[N][M];
memset(C, 0, sizeof C);
如果矩阵作为函数参数接收,你实际上得到的是一个指针,所以你必须更加小心:
void clear_matrix(double C[N][M]) {
memset(C, 0, sizeof(*C) * N);
}
或者可能更具可读性:
void clear_matrix(double C[N][M]) {
memset(C, 0, sizeof(C[0][0]) * N * M);
}
或者简单地说,如 Lundin 所建议的那样,但如果矩阵元素类型发生变化,则可能会中断:
void clear_matrix(double C[N][M]) {
memset(C, 0, sizeof(double[N][M]);
}
但是请注意,如果系统使用 IEEE-754 表示,memset()
会将矩阵数据清除为所有位零,这会将 double
值设置为 +0.0
,但不是完全便携。可移植版本将使用嵌套循环,如果适用于目标系统,good compiler 将生成相同的 memset
调用或内联代码:
#include <stddef.h>
#define N 10
#define M 20
void clear_matrix(double C[N][M]) {
for (size_t i = 0; i < N; i++) {
for (size_t j = 0; j < M; j++) {
C[i][j] = 0.0;
}
}
}
我有行 memset(C, 0, N*M);
,其中 C 是双精度矩阵。 (我正在使用 WSL。)
但是,如果我查看 gdb,矩阵中的某些元素设置为 -nan(0xffffffffffff8)
,而其他元素设置为 9.0096750001652956e-314
。
第一个没有给出任何错误,但是 +=
似乎没有改变任何东西(或者至少似乎没有让 nan 的东西消失),而第二个是如果元素未更改或仅具有 += 0
,则会出现问题,因为比较 if (0 == C[i][j])
会失败。
如果我手动将值设置为 0,则根本不会出现这些问题。
这是 WSL 的事情,还是 memset
有什么我不明白的地方?
M*N
是 items 的数量(双倍)但是 memset
期望 bytes 的数量.对于数组 double C[M][N]
,您需要执行 memset(C, 0, sizeof(C));
.
您没有完全初始化矩阵:memset()
需要一些字节。假设矩阵布局是线性的,无论是一维还是二维,您应该清除 sizeof(double) * N * M
字节。
如果您的矩阵定义为二维数组,您可以这样写:
#define N 10
#define M 20
double C[N][M];
memset(C, 0, sizeof C);
如果矩阵作为函数参数接收,你实际上得到的是一个指针,所以你必须更加小心:
void clear_matrix(double C[N][M]) {
memset(C, 0, sizeof(*C) * N);
}
或者可能更具可读性:
void clear_matrix(double C[N][M]) {
memset(C, 0, sizeof(C[0][0]) * N * M);
}
或者简单地说,如 Lundin 所建议的那样,但如果矩阵元素类型发生变化,则可能会中断:
void clear_matrix(double C[N][M]) {
memset(C, 0, sizeof(double[N][M]);
}
但是请注意,如果系统使用 IEEE-754 表示,memset()
会将矩阵数据清除为所有位零,这会将 double
值设置为 +0.0
,但不是完全便携。可移植版本将使用嵌套循环,如果适用于目标系统,good compiler 将生成相同的 memset
调用或内联代码:
#include <stddef.h>
#define N 10
#define M 20
void clear_matrix(double C[N][M]) {
for (size_t i = 0; i < N; i++) {
for (size_t j = 0; j < M; j++) {
C[i][j] = 0.0;
}
}
}