Comments (17)
I was planning to add a section about platform-specific notes in the documentation, perhaps I could add a warning about FreeBSD's issues with pow()
in there.
from mppp.
Hello @yurivict,
could you run the individual test and report back the output that it produces?
from mppp.
Here's the log:
$ ./work/.build/test/integer_pow
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
integer_pow is a Catch v2.1.1 host application.
Run with -? for options
-------------------------------------------------------------------------------
pow
-------------------------------------------------------------------------------
/usr/ports/math/mppp/work/mppp-0.9/test/integer_pow.cpp:201
...............................................................................
/usr/ports/math/mppp/work/mppp-0.9/test/integer_pow.cpp:189: FAILED:
REQUIRE( pow(integer{2}, 4.5l) == std::pow(2.l, 4.5l) )
with expansion:
22.6274 == 22.6274
===============================================================================
test cases: 1 | 0 passed | 1 failed
assertions: 15068 | 15067 passed | 1 failed
Cleaning up the mpz alloc cache.
Cleaning up MPFR caches.
from mppp.
I was able to reproduce the problem in a FreeBSD virtual machine. The problem here appears only in Release
builds and not in Debug
builds.
The statement pow(integer{2}, 4.5l)
should produce exactly the same identical result as std::pow(2.l, 4.5l)
, because both functions eventually end up calling the std::pow()
overload for long double
with base 2
and exponent 4.5
(and both numbers are exactly representable in a binary floating-point format). Indeed, on all my machines and operating systems, and on the automated unit testing pipeline, this is always the case. The only difference between those two expressions is that one can be computed at compile-time (std::pow(2.l, 4.5l)
), while the other cannot. However, on FreeBSD two slightly different values are being produced for those two expressions:
22.62741699796952078
22.62741699796951877
Perhaps related, it seems like on FreeBSD there might be some issue with the pow()
overload for long double
. When compiling this test, the linker warns me that:
warning: powl has lower than advertised precision
So my guess is that there is something funny going on with extended precision floating-point computations involving the C99 powl()
function. Do you have any idea of what might be going on?
Note that the test failure can be silenced easily by introducing some small tolerance instead of an exact equality, and this is an issue of the testing code and not of mp++ per se. But it would be nice to get to the bottom of it.
from mppp.
I'm getting the same results with this program:
#include <stdio.h>
#include <math.h>
#include <cmath>
int main(int argc, const char *argv[]) {
printf("pow(integer{2}, 4.5l) -> %.30Lf\n", pow(2, 4.5l));
printf("std::pow(2.l, 4.5l) -> %.30Lf\n", std::pow(2.l, 4.5l));
}
Output:
pow(integer{2}, 4.5l) -> 22.627416997969518774880270939320
std::pow(2.l, 4.5l) -> 22.627416997969518774880270939320
Pari gives 22.627416997969520780827019587355169257
with 28-decimal digit precision.
from mppp.
Ok I think I know what is going on. In a Debug
build, the compiler ends up calling the pow()
function at runtime for both expressions. This gives the result in double precision, not in long double precision, which is:
22.62741699796951877
So the linker warning is correct, the pow()
function for long double is not actually returning a result accurate to the last significant digit. If, however, the build is set to Release
, the compiler computes at compile time the result of the expression std::pow(2.l, 4.5l)
, presumably with some internal arbitrary precision library (GCC uses MPFR for compile time computations, not sure about clang). The result of std::pow(2.l, 4.5l)
computed at compile time is the correct result for long double
precision:
22.62741699796952078
As a proof, consider this program:
#include <iostream>
#include <cmath>
int main(int argc, char **)
{
std::cout.precision(40);
std::cout << std::pow(2l, 4.5l) << '\n';
std::cout << std::pow(static_cast<long double>(argc), 4.5l) << '\n';
}
compile it first without optimisation, and run it with ./a.out 2
. It will print:
22.62741699796951877488027093932032585144
22.62741699796951877488027093932032585144
If you recompile it with -O2
optimisation level, the output will be:
22.62741699796952078022060916850932699163
22.62741699796951877488027093932032585144
Can you confirm this?
from mppp.
Can you confirm this?
Yes, I got the same results.
from mppp.
Ok, I'll open a PR and put a workaround in the tests. Thanks for testing!
from mppp.
You're welcome!
from mppp.
PR is up at #134. I will do a 0.10 release in the next few days, so you can have a stable release with working tests on FreeBSD.
from mppp.
Great, thanks!
from mppp.
If this is due to a bug in FreeBSD, IMO you should just leave it failing as it is.
There's nothing wrong with mppp in this regard, no need to fix it.
Instead, I've created this bug report so that they can fix it: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=227179
from mppp.
Thanks for opening the report!
I just disabled that specific test on FreeBSD, I did not actually touch the library's code. Once the issue is fixed on FreeBSD's side, I can conditionally re-enable the test.
from mppp.
Sounds good!
Even better solution is, I think, to keep the failure, but to add an explanation for this case.
This is because 0 failures shouldn't be a goal. The goal should be to have users informed. -)
from mppp.
Yes, test failure + a warning and an explanation is better than to hide the failure IMO.
from mppp.
I've released mp++ 0.10 with the fixes and doc additions mentioned in this report. Please let me know if you have any further issues on FreeBSD!
from mppp.
It all works. I've updated the port. Thank you!
from mppp.
Related Issues (20)
- Version 0.15 installs libraries with mismatching version numbers HOT 10
- Use of GCC extension: The 'MPPP_WITH_QUADMATH' option was enabled but the '__float128' type does HOT 18
- How to use uint
- How to use uint256_t? HOT 3
- Rational benchmark HOT 5
- No powm or invert? HOT 2
- Use mp++ types in armadillo (proof of concept) HOT 5
- All tests fail in static initialization HOT 4
- arbitrary-precision integers are capped at 64 bytes? HOT 2
- compilation errors with Clang 6,7,8 HOT 3
- The test real_bessel fails on FreeBSD 12.2 HOT 10
- benchmarks for > 2 limbs + question on licensing HOT 1
- Cannot build mp++ 0.9 HOT 8
- [BUG] 0.24 fails with mpfr-4.1.0: error: expected unqualified-id HOT 13
- [BUG] Literal `_rq` performs conversion of string literal in runtime instead of compile time HOT 2
- Add support for decimal floats
- Alternative (better?) precision computations & approximations
- [BUG] MSVC C++20 compilation errors HOT 11
- [[maybe_unused]] ::mp_limb_t br; HOT 2
- [FEATURE] Vcpkg support
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mppp.