Handling of Inf and Nan for `nfloat`
Describe the bug
Multiplication of nfloat values does not seem to allow for infinite values even if the flag is set to NFLOAT_ALLOW_INF.
Steps to reproduce
Running the following code prints Return value: 2, which corresponds to GR_UNABLE.
gr_ctx_t ctx;
gr_ptr x, y, z;
int ret;
nfloat_ctx_init(ctx, 256, NFLOAT_ALLOW_INF);
GR_TMP_INIT3(x, y, z, ctx);
GR_MUST_SUCCEED(nfloat_pos_inf(x, ctx));
GR_MUST_SUCCEED(nfloat_one(y, ctx));
ret = nfloat_mul(z, x, y, ctx);
flint_printf("Return value: %d\n", ret);
Expected behavior
The documentation on how Inf and NaN values are handled is a bit sparse so I'm not entirely sure what the intended behavior is. But my understanding is that with NFLOAT_ALLOW_INF you should be able to, say, multiply a finite, non-zero, number with infinity and get infinity as a result. As the above code shows this simply returns GR_UNABLE at the moment.
For addition, subtraction and division it seems to instead always return NaN, and only succeeds if NFLOAT_ALLOW_NAN is set. Running the following code prints nan three times.
gr_ctx_t ctx;
gr_ptr x, y, z;
int ret;
nfloat_ctx_init(ctx, 256, NFLOAT_ALLOW_INF | NFLOAT_ALLOW_NAN);
GR_TMP_INIT3(x, y, z, ctx);
GR_MUST_SUCCEED(nfloat_pos_inf(x, ctx));
GR_MUST_SUCCEED(nfloat_one(y, ctx));
GR_MUST_SUCCEED(nfloat_add(z, x, y, ctx));
gr_println(z, ctx);
GR_MUST_SUCCEED(nfloat_sub(z, x, y, ctx));
gr_println(z, ctx);
GR_MUST_SUCCEED(nfloat_div(z, x, y, ctx));
gr_println(z, ctx);
I couldn't find any occurrence of NFLOAT_ALLOW_INF or NFLOAT_ALLOW_NAN in the directory src/nfloat/test/, so it seems like the code paths handling infinities and NaNs are not tested at all at the moment.
Operations on Inf and NaN for nfloat are essentially not implemented. The definitions are in place for doing so in the future.
Okay, good to know!