-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Make 0 divided by 0 results in NaN consistently #2253
Conversation
I ran into a related issue today when using $ jq -n 'nan | ., if . then "true" else "false" end'
null
"true"
$ jq -n 'nan | ., (. // "alt")'
null
null Treating it as false might be even more confusing? so maybe error is better? |
That is incorrect. |
Yes, sorry i was a bit unclear, that was what i meant, |
@wader - Making a special case for just |
Now realized that i read the PR commit message a bit fast, I understood it as making it consistently throw error on division by zero. Yeah agree, it's probably too late to change any of this now. |
1199685
to
e2b3b29
Compare
Thank you. |
if (jv_number_value(b) == 0.0 && jv_number_value(a) != 0.0) | ||
return type_error2(a, b, "cannot be divided because the divisor is zero"); | ||
jv r = jv_number(jv_number_value(a) / jv_number_value(b)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is actually problematic because division by 0 is unspecified for all values in C, so 0.0/0.0
will be undefined behaviour.
If we want to make 0/0
return nan, we should hardcode that case.
diff --git a/src/builtin.c b/src/builtin.c
index 09ffc04..1b4aec2 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -383,8 +383,13 @@ static jv f_multiply(jq_state *jq, jv input, jv a, jv b) {
static jv f_divide(jq_state *jq, jv input, jv a, jv b) {
jv_free(input);
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
- if (jv_number_value(b) == 0.0 && jv_number_value(a) != 0.0)
- return type_error2(a, b, "cannot be divided because the divisor is zero");
+ if (jv_number_value(b) == 0.0) {
+ if (jv_number_value(a) != 0.0)
+ return type_error2(a, b, "cannot be divided because the divisor is zero");
+ jv_free(a);
+ jv_free(b);
+ return jv_number(NAN);
+ }
jv r = jv_number(jv_number_value(a) / jv_number_value(b));
jv_free(a);
jv_free(b);
0/0
is folded tonan
on parsing but0 as $x | $x/0
throws a zero-division error so0/0
is not equal to0 as $x | $x/0
. This is not intuitive. I think0 as $x | $x/0
should benan
as well as0/0
is.