Port number's mantissa to std::vector#544
Port number's mantissa to std::vector#544janisozaur wants to merge 7 commits intomicrosoft:masterfrom
Conversation
|
|
||
| // Loop over all the relative digits from MSD to LSD | ||
| for (ptr = &(a->mant[a->cdigit - 1]); cdigits > 0; ptr--, cdigits--) | ||
| for (ptr = &(a.mant[a.cdigit - 1]); cdigits > 0; ptr--, cdigits--) |
There was a problem hiding this comment.
The unit tests are failing, and I think the problem is here--we're calling a.mant[-1].
One reasonable fix would be to rewrite this as a while loop so we check cdigits first:
while(cdigits > 0)
{
ptr = &(a.mant[a.cdigit - 1]);
// etc.
ptr--;
cdigits--;
}
|
I rebased this on top of already approved #545 to preempt minor conflict and fixed some issues I found. This might address the warnings raised previously, I'd like to hear back from the test suite, would be nice to have it fixed |
|
/azp run |
|
Pull request contains merge conflicts. |
|
Sorry for the test pipeline outage earlier. The unit tests are still failing with the same issue, unfortunately. |
5b5046f to
ce8d263
Compare
|
Judging by the error message reported, the tests are failing because of infrastructure still.
|
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Still working on this CI infrastructure issue--I'm waiting for another team to investigate. I tried running the unit tests locally, and I'm still seeing failures. The next one I see is a vector subscript out of range in mulnumx, line 42. There wasn't an obvious logic change there, so a deeper investigation will be needed. |
|
How can I get size of mantissa in its previous (flexible array) form? The equivalent of |
| throw(CALC_E_INVALIDRANGE); | ||
| } | ||
| return (pnumret); | ||
| NUMBER num = NUMBER(); |
There was a problem hiding this comment.
This would create a default-constructed value, which will have sign equal 1:
That's unlike the current/old code, which would initialise it to 0 (via zmalloc call, which calls calloc underneath).
| { | ||
| // Remove them. | ||
| memmove(pnum->mant, pmant, (int)(cdigits * sizeof(MANTTYPE))); | ||
| copy(pmant, pmant + cdigits, pnum.mant.begin()); |
There was a problem hiding this comment.
In case the elements overlap, the result of std::copy is undefined, unlike with memmove
| if (c.mant.begin() != ++ptrc) | ||
| { | ||
| destroynum(num); | ||
| copy(ptrc, ptrc + cdigits, c.mant.begin()); |
There was a problem hiding this comment.
memmove vs std::copy again
| // radix being used. | ||
| int32_t exp = 0; // The offset of digits from the radix point | ||
| // (decimal point in radix 10) | ||
| std::vector<MANTTYPE> mant; |
There was a problem hiding this comment.
It seems cdigit is used as count of entries in the flexible array in the long form, is that correct? Additionally, cdigits usage seems to suggest such arrays used to have at least one element defaulting to zero, is that correct? Since vector by default doesn't contain any values, perhaps default-initialising it with a single zero would address the current problems:
| std::vector<MANTTYPE> mant; | |
| std::vector<MANTTYPE> mant{0}; |
|
@mcooley I highlighted some possible differences, could you review them? |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Okay, looks like we’ve finally worked around the CI infrastructure issues. Thanks for flagging all these spots to double-check. I am about to head out on vacation for a few days, but I will take a closer look at these next week. |
|
@mcooley is there any way I can get Azure to produce actual error messages, instead of the rather unhelpful ? |
| { | ||
| m_mantissa.reserve(p->cdigit); | ||
| copy(p->mant, p->mant + p->cdigit, back_inserter(m_mantissa)); | ||
| m_mantissa.reserve(p.cdigit); |
There was a problem hiding this comment.
Why not use resize and thence avoid back_inserter ?
dc1e229 to
000733d
Compare
|
All the CI runs are green now! @mcooley can you review now? |
danbelcher-MSFT
left a comment
There was a problem hiding this comment.
Thanks for getting this working! My main concern with this change is around performance and clarity of the codebase. Previously we were passing and manipulating everything as PNUMBER and now we've switched to NUMBER. In some cases, there is no performance loss, such as changing from PNUMBER to NUMBER &, but I'm generally concerned that we may have introduced additional copies etc that weren't there previously. There are a number of places where PNUMBER was changed to NUMBER* but could have been changed to NUMBER& for increased safety (I recognize it's a cascading change that is outside the scope of your work here, but it's worth bringing up). There's also some confusion in the codebase in the distinction between Number and NUMBER, as well as the naming of data members (pq is not a pointer). Number is intended to be the modern replacement for the NUMBER POD. Hopefully we see the codebase start to move functionality into the Number/Rational classes and we can drop NUMBER/RAT altogether.
| Number::Number(PNUMBER p) noexcept | ||
| : m_sign{ p->sign } | ||
| , m_exp{ p->exp } | ||
| Number::Number(NUMBER p) noexcept |
There was a problem hiding this comment.
| Number::Number(NUMBER p) noexcept | |
| explicit Number::Number(const NUMBER& p) noexcept |
| } | ||
|
|
||
| PNUMBER Number::ToPNUMBER() const | ||
| NUMBER Number::ToNUMBER() const |
There was a problem hiding this comment.
| NUMBER Number::ToNUMBER() const | |
| explicit Number::operator NUMBER() const |
| *ptrRet++ = digit; | ||
| } | ||
|
|
||
| NUMBER ret = _createnum(static_cast<uint32_t>(this->Mantissa().size()) + 1); |
There was a problem hiding this comment.
Can we get rid of _createnum and use a constructor instead?
| // Mantissa specified, convert to number form. | ||
| PNUMBER pnummant = StringToNumber(mantissa, radix, precision); | ||
| if (pnummant == nullptr) | ||
| optional<NUMBER> pnummant = StringToNumber(mantissa, radix, precision); |
There was a problem hiding this comment.
std::optional works well with auto and pointer semantics:
| optional<NUMBER> pnummant = StringToNumber(mantissa, radix, precision); | |
| auto pnummant = StringToNumber(mantissa, radix, precision); | |
| if (!pnummant) | |
| { | |
| ... | |
| } |
| } | ||
|
|
||
| if (round != nullptr) | ||
| if (round.has_value()) |
There was a problem hiding this comment.
| if (round.has_value()) | |
| if (round) |
| destroynum(tmp); | ||
| tmp = lasttmp; | ||
| lasttmp = nullptr; | ||
| lasttmp = optional<NUMBER>(); |
There was a problem hiding this comment.
| lasttmp = optional<NUMBER>(); | |
| lasttmp = nullopt; |
| { | ||
| PNUMBER pp; | ||
| PNUMBER pq; | ||
| NUMBER pp; |
There was a problem hiding this comment.
| NUMBER pp; | |
| NUMBER p; | |
| NUMBER q; |
The names pp and pq are shorthand for pointer to p and pointer to q. There will be a lot of change in the codebase if you rename these, but we're also adding confusion now that the names have embedded type information that isn't actually correct.
| OutputDebugString(outputString.str().c_str()); \ | ||
| } \ | ||
| _destroynum(x), (x) = nullptr | ||
| { |
There was a problem hiding this comment.
I don't think this is actually valid?
|
I've rebased it and updated to include changes required after #498, but haven't addressed the review comments yet. |
|
I started writing some benchmarks using google benchmark, but have never really finished them to a point where they would be worth submitting and eventually lost interest in that, as other things took my time away. I can't say I fully agree with the argument about possible performance loss, when there is no benchmark available in the upstream project, so I will simply address the review comments as they are now. |
6b39c64 to
9d0cec9
Compare
These are the changes extracted from microsoft#211 that port number's mantissa from flexible member arrays, a non-standard C++ extension, to std::vector, which enables compilation and linkage with clang. @fwcd is the original author of these changes, I (@janisozaur) merely rebased them on top of current master. The rebase was luckily fairly straight-forward, with the only real conflict coming from 7a7ceb5 (microsoft#412), but was trivial to fix.
|
Closing this since it's become stale and we haven't had time to thoroughly investigate the regressions in our primary environment (Visual Studio on Windows). Thanks for your interest in working on portability; we hope that some of these changes can be contributed in smaller pieces in the future. |
|
I've rebased the code here to a branch 'mantissa-202110' in my fork. This is currently under testing, hopefully will submit another PR at some point. |
These are the changes extracted from #211 that port number's mantissa
from flexible member arrays, a non-standard C++ extension, to
std::vector, which enables compilation and linkage with clang.
@fwcd is the original author of these changes, I (@janisozaur) merely
rebased them on top of current master.
The rebase was luckily fairly straight-forward, with the only real
conflict coming from 7a7ceb5
(#412), but was trivial to
fix.