-
Notifications
You must be signed in to change notification settings - Fork 111
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
variable precision arithmetic between complex and rational yields incorrect precision #308
Comments
Same for all four primary arithmetic operations -- +-*/, with operands in either order. |
This follows on #75 |
Confirmed. I have a partial fix, but further testing reveals a whole swathe of situations where the current situation breaks down. To recap, we have assignment-preserves-precision-of-source. And this should all be working now for same-type operations. However, things get screwy with integer and rational types. The question is basically this: if I assign an integer to a variable precision floating point (or complex) type, then what is the precision of the result? Options are: Variable precision integers:
Option (1) is a non-starter as this fails catastrophically:
We currently do (2). For fixed precision integers:
1 and 2 are non starters as before, we're currently somewhere around (4), modulo any bugs. For consistency, I'm considering (3). Rationals: |
I wanted to share a few of my own thoughts about this issue. My codebase relies mostly on floating point calculations, with some values which have fixed values held as integers/rationals/very high precision numbers, which we down-sample from into floats. So, for me, arithmetic between mixed arbitrary precision ints and rationals is not the highest priority. My workaround for this issue is to always downsample to floats. But I lack a systematic way of preventing mixed-type arithmetic at this time. I'd be content with having a way to compute |
Do you think that including something like a type caste operator(in order to specify the output precision you are looking for) in the documentation could be a good fix here? Something like this:
|
Yes, definitely, but there are other issues to work through as well to get everything consistent.... more on that soon. In the meantime, something like this:
Works right now. The catch is that the 2-arg constructor means something else for a complex number, so you need to construct the corresponding scalar type. |
I'm struggling with this conversion. I'd like to explain a bit. My code is templated on scalar type, and I call the type I'm wondering if you have any suggestions for how to deal with this, in the paradigm of APPoS, where construction of a variable-precision number will be very high, constructing from integral and rational types. |
Well... I never said the constructor was a good solution: like you say, it's not generic. I'm contemplating in addition to a ::default_precision() member, adding some member flags that control this behaviour. The alternative is a non-member cast operator, but then this is Boost.Multiprecision specific, where as a flag would be set at the same time as you set precision, before any generic code is called. As a stopgap, if you have control of the generic portion of the code, then there's nothing to stop you from writing a cast operator now - the default version would do nothing, then overload for variable precision Multiprecision types. |
Ah, gotcha. I use my own |
this is in reference to boostorg/multiprecision#308
since APPoS, and boostorg/multiprecision#308
I see you working on this issue! I'd love to test out the code when you get it to such a ready state! |
Here's an interesting currently-failing test case I just found:
The output I am getting:
I think I should get a number of precision 20 out of this, not 19. Interestingly, I observe that this test case passes:
I think that I'm concluding that the precisions for the two backends need to be coupled? From this test case, which also fails, I can draw another conclusion. Test:
Output:
My conclusion is that for these cases, it's I do hope this is addressed in the work you're doing! I'm excited to have a more predictable world of default precisions. Thanks! |
Thanks, those are plainly absurd, I'm slowly working through the permutations, but I haven't got to mixed types yet.... that's next! |
I'll note that I didn't find this until now because I hadn't tested |
Will any of the behaviour you're implementing be adjustable at compile time? |
At present I'm focused on runtime. But it's not lost on me that some of the functions could be made constexpr if the user was willing to restrict the runtime options. |
I finally ran into the boundary of where manual type conversion will let me work around this bug -- my Boost.Python code. I enable arithmetic of mixed numeric types using visitor pattern and tons of templates, and to manually write the code exposing arithmetic between mpq_rational and mpc_complex is prohibitive. I guess I'm saying "I'm grateful you're working on this, because my project needs it". Thanks! |
Should now be addressed in develop |
I'm using Boost 1.75, via Homebrew. I have a test failing in my code, because the precision of the result of mixed-type arithmetic (multiplication at least) between complex numbers and rational numbers is incorrect. Code for test:
The precision of
c
should be 30 -- it's coming to me as 646392383.The text was updated successfully, but these errors were encountered: