Skip to content

Implement missing Math logarithm functions from ES6 #3617

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

Merged
merged 1 commit into from
Apr 4, 2020

Conversation

rwalczyna
Copy link
Contributor

Math.log2, Math.log10, Math.log1p, Math.expm1

C implementation ported from fdlibm

Part of Issue #3568

JerryScript-DCO-1.0-Signed-off-by: Rafal Walczyna r.walczyna@samsung.com

@rerobika rerobika requested a review from ossy-szeged March 16, 2020 13:51
@rerobika rerobika added ES2015 Related to ES2015 features jerry-libm Related to the jerry-libm library labels Mar 16, 2020
assert(isNaN(Math.log1p(NaN)));
assert(isNaN(Math.log1p(-42)));
assert(isNaN(Math.log1p(-3.0)));
assert(Math.log1p(n_zero) === n_zero);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto


assert(isNaN(Math.expm1(NaN)));
assert(Math.expm1(p_zero) === p_zero);
assert(Math.expm1(n_zero) === n_zero);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing to -0.0 won't work with == or ===, because 0.0 will be equal to -0.0.

Previously I found and fixed a similar bug, you can see
the proper compare in tests/jerry/es2015/math-trunc.js .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, you are right, it helped me to find bug in source code ;)

Comment on lines 573 to 577
/* ES6 20.2.2.15 Math.expm1(-0.0) = -0.0 */
if ((x == 0.0) && (ecma_number_is_negative (x)))
{
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check should be inside #ifdef JERRY_LIBM_MATH_H guard,
because exp in libm conforms to the spec without this workaround.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exp(x) function conforms to specification, but for (0-) "left" and (0+) "right" "0" - but in this case it should distinguish "left" and "right" "1", because we are subtracting 1 from exp(x) result.

I deleted this check, build with tools/build.py --profile=es2015-subset --debug --show-opcodes=ON --jerry-libm=OFF --link-lib=m --clean and unfortunately test fails.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I got it. In this case we should use expm1 and log1p instead of exp and log if we build with (GNU) libm, the new tests pass with them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add native implementation (not reuse of exp()) to provide better accuracy for small numbers (both for expm1 and log1p).

Comment on lines 583 to 587
/* ES6 20.2.2.21 Math.log1p(-0.0) = -0.0 */
if ((x == 0.0) && (ecma_number_is_negative (x)))
{
break;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

* software is freely granted, provided that this notice
* is preserved.
*
* @(#)e_log2.c 1.3 95/01/18
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know the origin of this file? I can't see e_log2.c here: https://www.netlib.org/fdlibm/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Source: https://github.com/JuliaMath/openlibm/blob/master/src/e_log2.c
It looks exactly the same as files on netlib.org, but I couldn't find original place with all fdlibm files - something like "SunSoft repository"

@rwalczyna
Copy link
Contributor Author

I added native implementations of expm1() and logp1().
This way the accuracy is better and there is no need to add extra checks to ecma-builtin-math.c

Copy link
Member

@dbatyai dbatyai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ossy-szeged
Copy link
Contributor

LGTM (informal)

Copy link
Contributor

@ossy-szeged ossy-szeged left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We updated the reference platform recently to Ubuntu 18.04 (it was 14.04 previously),
which has newer cppcheck and reported 2 minor warnings on this PR.

}
else
{
twopk.as_int.hi = 0x3ff00000 + (k << 20); /* 2^k */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cppcheck reported this warning:
jerry-libm/expm1.c:243: portability(shiftNegativeLHS): Shifting a negative value is technically undefined behaviour

k should be casted to unsigned int to make cppcheck happy (and eliminate UB):
((unsigned int)(k) << 20)

else
{
/* log1p(x<-1) = NaN */
return (x - x) / (x - x);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cppcheck reported this warning:
jerry-libm/log1p.c:130: style(duplicateExpression): Same expression on both sides of '/'.

You can simply use NAN instead of this expression. (defined in jerry-libm-internal.h)

Math.log2, Math.log10, Math.log1p, Math.expm1

C implementation ported from fdlibm

Part of Issue jerryscript-project#3568

JerryScript-DCO-1.0-Signed-off-by: Rafal Walczyna r.walczyna@samsung.com
@rwalczyna
Copy link
Contributor Author

Thanks, I rebased the commit and fixed those lines.

@dbatyai dbatyai requested review from ossy-szeged and rerobika April 1, 2020 09:14
Copy link
Member

@rerobika rerobika left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ES2015 Related to ES2015 features jerry-libm Related to the jerry-libm library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants