如何在C中用NAN填充整数/size_t类型的向量/矩阵。

huangapple go评论67阅读模式
英文:

How to populate a vector / matrix of int / size_t with NAN in C

问题

根据我理解,NAN 可以分配给 double 类型的变量,但不一定适用于 int / size_t 类型。

是否仍然有一种方法可以用 NAN 来填充 int / size_t 类型的向量/矩阵?

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct {
  size_t nrows, ncols;
  size_t *array;
} Matrix ;

size_t ncol = 5;
size_t nrow = 1;

void print_matrix(Matrix * matrix);

int main()
{
  Matrix *mat1 = (Matrix *) malloc(sizeof(Matrix));
  mat1->nrows = nrow;
  mat1->ncols = ncol;
  mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));
  if (mat1 == NULL)
  {
    printf("Could not allocate memory\n");
    exit(EXIT_FAILURE);
  }
  else
  {
    mat1->nrows = nrow;
    mat1->ncols = ncol;
    mat1->array = (size_t *) malloc(mat1->nrows * mat1->ncols * sizeof(*mat1->array));
    for (size_t row =0; row<mat1->nrows; row++)
    {
      for (size_t col =0; col<mat1->ncols; col++)
      {
        mat1->array[row * ncol + col] = NAN;
      }
    }
    print_matrix(mat1);
    free(mat1);
  }
}

void print_matrix(Matrix * matrix)
{
  for (size_t row =0; row<matrix->nrows; row++)
  {
    for (size_t col =0; col<matrix->ncols; col++)
    {
      printf("%zu ", matrix->array[row * ncol + col]);
    }
    printf("\n");
  }
}
英文:

As far as I understood, NAN can be allocate to a double type variable but not necessarily to int / size_t

Is there still a way to populate a vector/matrix of type int / size_t with NAN?

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;math.h&gt;

typedef struct {
  size_t nrows, ncols;
  size_t *array;
} Matrix ;

size_t ncol = 5;
size_t nrow = 1;

void print_matrix(Matrix * matrix);

int main()
{
  Matrix *mat1 = (Matrix *) malloc(sizeof(Matrix));
  mat1-&gt;nrows = nrow;
  mat1-&gt;ncols = ncol;
  mat1-&gt;array = (size_t *) malloc(mat1-&gt;nrows * mat1-&gt;ncols * sizeof(*mat1-&gt;array));
  if (mat1 == NULL)
  {
    printf(&quot;Could not allocate memory\n&quot;);
    exit(EXIT_FAILURE);
  }
  else
  {
    mat1-&gt;nrows = nrow;
    mat1-&gt;ncols = ncol;
    mat1-&gt;array = (size_t *) malloc(mat1-&gt;nrows * mat1-&gt;ncols * sizeof(*mat1-&gt;array));
    for (size_t row =0; row&lt;mat1-&gt;nrows; row++)
    {
      for (size_t col =0; col&lt;mat1-&gt;ncols; col++)
      {
        mat1-&gt;array[row * ncol + col] = NAN;
      }
    }
    print_matrix(mat1);
    free(mat1);
  }
}

void print_matrix(Matrix * matrix)
{
  for (size_t row =0; row&lt;matrix-&gt;nrows; row++)
  {
    for (size_t col =0; col&lt;matrix-&gt;ncols; col++)
    {
      printf(&quot;%zu &quot;, matrix-&gt;array[row * ncol + col]);
    }
    printf(&quot;\n&quot;);
  }
}

答案1

得分: 4

As far as I understood, NAN can be [assigned] to a double type variable

根据我的理解,NAN 可以分配给 double 类型的变量。

That is correct. NaN is one of the special values defined for IEEE-754-based types like float and double.<sup>1</sup>

这是正确的。NaN 是在 IEEE-754 基础类型,如 floatdouble 中定义的特殊值之一。

but not necessarily to int / size_t

但不一定可以分配给 intsize_t

Right. NaN is not a value defined for integral types int or size_t.

正确。NaN 是对整数类型 intsize_t 定义的值之一。

You can't store NaN in an integral variable for the same reason you can't store 3.14 in an integral variable. It's just not one of the values that integral types can hold.

你不能将 NaN 存储在整数变量中,原因与你不能将 3.14 存储在整数变量中相同。这不是整数类型可以保存的值之一。

(One of the formal definitions of a data type in programming is that it is a set of values, and a set of operations on those values. For types float and double — but only for those types — NaN is one of the values. Actually, there are multiple NaN values, but that's a different story.)

在编程中,数据类型 的正式定义之一是它是一组值,以及对这些值的一组操作。对于 floatdouble 类型 - 但仅限于这些类型 - NaN 是其中的一个值。实际上,存在多个 NaN 值,但这是另一回事。

For the floating-point types, NaNs are sentinel values, well-defined "not a value" values. Some types have sentinel values, and some don't. For example, for pointer types, NULL is the sentinel "not a valid pointer" value. In C strings, the null character \0 is a sentinel value marking the end of the string. On the other hand, when you call getchar, EOF is the "not a character" value. (This doesn't make EOF a sentinel value for type char, though, since EOF is not a value of type char.)

对于浮点类型,NaN哨兵值,明确定义的“不是一个值”的值。某些类型具有哨兵值,而某些类型则没有。例如,对于指针类型,NULL 是哨兵值,表示“无效指针”值。在C字符串中,空字符\0 是表示字符串末尾的哨兵值。另一方面,当调用 getchar 时,EOF 是“不是字符”的值。(这并不使EOF 成为 char 类型的哨兵值,因为 EOF 不是 char 类型的值。)

But there is no predefined sentinel value for any of the other integral types. The way integers are used in real programs, there's no value that could be reserved as a sentinel that might not also be a valid value.

但是,对于其他整数类型,没有预定义的哨兵值。在实际程序中使用整数的方式,没有可以保留为哨兵的值,这个值可能也是有效值。

If you have an integer variable and you need a sentinel value, you will need to define one of your own, if you can. For example, if you know that your values are always positive, you can use -1 as a sentinel value. But this will be, at best, a convention: the value -1 won't be treated specially by the language, or the CPU — it's just another integer value.

如果你有一个整数变量并且需要一个哨兵值,如果可以的话,你需要自己定义一个。例如,如果你知道你的值始终为正,你可以使用 -1 作为哨兵值。但这最多只是一个约定:值 -1 不会被编程语言或CPU特殊对待 - 它只是另一个整数值。

It's great that floating-point and pointer types have sentinel values, and it's sometimes a nuisance that other types don't. The ad hoc conventions one has to use when trying to define sentinel values for other types frequently lead to various nuisances. In order for EOF to work as a sentinel value for getchar, programmers have to remember to always store getchar's return value in a variable of type int, not char. A function like read that returns a number of characters read, or -1 to indicate an error, is difficult to define a good return type for, since it has to be signed to accommodate -1, but could otherwise be unsigned.<sup>2</sup> The function mktime, which converts a broken-down time structure back to an integral time_t value, returns -1 for error, meaning you can't unambiguously tell whether you've gotten an error, or have successfully converted the time 23:59:59 on December 31, 1969.

很好,浮点数和指针类型具有哨兵值,但其他类型没有时有时可能会让人感到不便。在尝试为其他类型定义哨兵值时,必须使用临时约定,这经常会导致各种不便。为了使 EOF 作为 getchar 的哨兵值工作,程序员必须记住[始

英文:

> As far as I understood, NAN can be [assigned] to a double type variable

That is correct. NaN is one of the special values defined for IEEE-754-based types like float and double.<sup>1</sup>

> but not necessarily to int / size_t

Right. NaN is not a value defined for integral types int or size_t.

You can't store NaN in an integral variable for the same reason you can't store 3.14 in an integral variable. It's just not one of the values that integral types can hold.

(One of the formal definitions of a data type in programming is that it is a set of values, and a set of operations on those values. For types float and double — but only for those types — NaN is one of the values. Actually, there are multiple NaN values, but that's a different story.)

For the floating-point types, NaNs are sentinel values, well-defined "not a value" values. Some types have sentinel values, and some don't. For example, for pointer types, NULL is the sentinel "not a valid pointer" value. In C strings, the null character \0 is a sentinel value marking the end of the string. On the other hand, when you call getchar, EOF is the "not a character" value. (This doesn't make EOF a sentinel value for type char, though, since EOF is not a value of type char.)

But there is no predefined sentinel value for any of the other integral types. The way integers are used in real programs, there's no value that could be reserved as a sentinel that might not also be a valid value.

If you have an integer variable and you need a sentinel value, you will need to define one of your own, if you can. For example, if you know that your values are always positive, you can use -1 as a sentinel value. But this will be, at best, a convention: the value -1 won't be treated specially by the language, or the CPU — it's just another integer value.

It's great that floating-point and pointer types have sentinel values, and it's sometimes a nuisance that other types don't. The ad hoc conventions one has to use when trying to define sentinel values for other types frequently lead to various nuisances. In order for EOF to work as a sentinel value for getchar, programmers have to remember to always store getchar's return value in a variable of type int, not char. A function like read that returns a number of characters read, or -1 to indicate an error, is difficult to define a good return type for, since it has to be signed to accommodate -1, but could otherwise be unsigned.<sup>2</sup> The function mktime, which converts a broken-down time structure back to an integral time_t value, returns -1 for error, meaning you can't unambiguously tell whether you've gotten an error, or have successfully converted the time 23:59:59 on December 31, 1969.


Footnote 1: Types float and double aren't necessarily based on the IEEE-754 definitions in C, but on most systems these days, they are.

Footnote 2: I believe that's why read is defined as returning a value of type ssize_t, and I believe type ssize_t is a "signed size_t", or in other words, "A value that would otherwise be unsigned, just like size_t is, except it has to be signed so it can return -1".

huangapple
  • 本文由 发表于 2023年3月3日 20:54:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75627352.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定