-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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.