Skip to content

Comments

Fix tan returning -nan for inputs where abs(x) >= 2^63#5114

Merged
dlang-bot merged 1 commit intodlang:masterfrom
pineapplemachine:fix_tan_asm
Jun 27, 2017
Merged

Fix tan returning -nan for inputs where abs(x) >= 2^63#5114
dlang-bot merged 1 commit intodlang:masterfrom
pineapplemachine:fix_tan_asm

Conversation

@pineapplemachine
Copy link
Contributor

@pineapplemachine pineapplemachine commented Feb 10, 2017

The fptan instruction pushes a 1.0 onto the FPU register stack after a successful operation, but when abs(input) >= 2^63 the C2 flag is set to indicate that the input was out of bounds, and it doesn't push the 1.0.

Prior to this PR, the top value of the FPU stack was popped irrespective of whether C2 was set, which in the case of an out-of-bounds input caused the input to be removed from the stack and ultimately resulted in an incorrect return value of -nan. This PR changes this behavior, only popping after fptan when C2 was not set.

See: http://x86.renejeschke.de/html/file_module_x86_id_109.html

@pineapplemachine
Copy link
Contributor Author

pineapplemachine commented Feb 10, 2017

Attn @WalterBright who I assume wrote the original asm?

@WebDrake
Copy link
Contributor

git blame suggests it was @donc who wrote the original implementation. Don, can you advise?

@andralex
Copy link
Member

cc @ibuclaw @redstar @klickverbot

@ibuclaw
Copy link
Member

ibuclaw commented Feb 13, 2017

Missing unittests?

@ibuclaw
Copy link
Member

ibuclaw commented Feb 13, 2017

We should probably document what is the domain of this function, as well as others. And what the behaviour should be when it is too far outside that range - I'd have to do some looking up on that though.

@pineapplemachine
Copy link
Contributor Author

@ibuclaw on that topic it's worth noting that expi suffers from a similar issue, though in that case it's due to having no handling for the case of an out-of-range input rather than having incorrect handling. An example of correctly handling out-of-range inputs to fsincos is here: https://github.com/pineapplemachine/mach.d/blob/master/mach/math/trig/sincos.d#L77

I added unit tests to verify the new behavior. The output is imprecise for such large inputs, but I think imprecision is preferable to NaN.

@ibuclaw
Copy link
Member

ibuclaw commented Feb 13, 2017

Yeah, I just looked at the cephes code that I used for reference for the generic implementations (gdc uses this). It says that it should return 0.0 if x > 2^39 for 80-bit, and x > 2^30 for 64-bit reals.

@pineapplemachine
Copy link
Contributor Author

It's worth noting that the documentation here suggests using fprem to bring the input into range when it's outside of it, which is what the implementation was unsuccessfully doing before and should correctly do now.

Either way is fine by me, but if my change isn't the desired behavior I'll leave it up to someone else to make it right.

@pineapplemachine
Copy link
Contributor Author

pineapplemachine commented Jun 22, 2017

This is a straightforward bugfix that does not alter functionality except fixing the presumed undesirable case of returning NaN for large positive or negative inputs, in which cases the result may not be accurate but is still well-defined. The functionality change made by this PR was clearly the intended functionality when the implementation was written. The diff is tiny; this is the least intrusive conceivable change that will address this bug.

I suggest that this PR should be merged and, if there are any decisions made later about the desired behavior of the tangent function for large positive or negative inputs, then those should be addressed in a separate PR and not withhold the correction of what is obviously incorrect and unexpected behavior.

@wilzbach
Copy link
Contributor

that will address this bug.

Please add a bugzilla issue and link it with this PR, so that the change is visible in the changelog.
Basically it's just a git commit message starting with "Fix" and then followed by the bugzilla title. More infos:

https://github.com/dlang-bots/dlang-bot

I suggest that this PR should be merged

CIs need to pass first - you seem to have trailing whitespace. Do you need help fixing this?

@don-clugston-sociomantic
Copy link
Contributor

git blame suggests it was @donc who wrote the original implementation. Don, can you advise?

It actually wasn't written by me, the code dates back to at least DMD 0.043, it was probably written by Walter in 2003 or earlier, maybe even in the 80's.
LGTM.

@JackStouffer
Copy link
Contributor

@pineapplemachine With don signing off on this, just fix the whitespace issue and I'll pull.

@pineapplemachine
Copy link
Contributor Author

The spaces have been nuked

@pineapplemachine
Copy link
Contributor Author

Also added an issue to bugzilla: https://issues.dlang.org/show_bug.cgi?id=17562

The fptan instruction pushes a 1.0 onto the FPU register stack after a
successful operation, but when abs(input) >= 2^63 the C2 flag is set to
indicate that the input was out of bounds, and it doesn't push the 1.0.

Prior to this PR, the top value of the FPU stack was popped irrespective
of whether C2 was set, which in the case of an out-of-bounds input
caused the input to be removed from the stack and ultimately resulted in
an incorrect return value of -nan. This PR changes this behavior, only
popping after fptan when C2 was not set.

See: http://x86.renejeschke.de/html/file_module_x86_id_109.html

* Added unit tests for handling out-of-range inputs of fptan
@PetarKirov
Copy link
Member

PetarKirov commented Jun 27, 2017

Auto-merging since Don gave LGTM.
I've rebased the PR in order to squash the commits and to add the number of the fixed Bugzilla issue to the commit message.

@wilzbach
Copy link
Contributor

wilzbach commented Jun 27, 2017

@ZombineDev

You forgot to approve the PR:

2017-06-27T20:32:35.218672+00:00 app[web.1]: [275DAFDA:2093F7DA WRN] PUT https://api.github.com/repos/dlang/phobos/pulls/5114/merge failed;  Method Not Allowed 405.
2017-06-27T20:32:35.218685+00:00 app[web.1]: [275DAFDA:2093F7DA WRN] {"message":"At least one approved review is required by reviewers with write access.","documentation_url":"https://help.github.com/articles/about-protected-branches"}

I think the bot could/should warn about this, see also:
dlang/dlang-bot#104 or dlang/dlang-bot#108

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @pineapplemachine! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.

Some tips to help speed things up:

  • smaller, focused PRs are easier to review than big ones

  • try not to mix up refactoring or style changes with bug fixes or feature enhancements

  • provide helpful commit messages explaining the rationale behind each change

Bear in mind that large or tricky changes may require multiple rounds of review and revision.

Please see CONTRIBUTING.md for more information.

Bugzilla references

Fix Bugzilla Description
17562 Tangent function returns NaN for abs(input) >= 2^63

@wilzbach
Copy link
Contributor

Closed/reopened to show that the bot recognized the issue (not sure what went wrong with the first hook -I have enabled more logging (I have opened a PR to enable more logging: dlang/dlang-bot#105)

Auto-merging since Don gave LGTM.

Hehe, our bot requires this formally ;-)

@dlang-bot dlang-bot merged commit e4afaca into dlang:master Jun 27, 2017
@ibuclaw
Copy link
Member

ibuclaw commented Jun 28, 2017

Just saw this, was the cephes (non x86 as) path tested? If not the gdc and ldc gods will come for you. 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants