std.math: Add IEEE 128-bit implementation of lrint().#4036
std.math: Add IEEE 128-bit implementation of lrint().#4036redstar wants to merge 1 commit intodlang:masterfrom
Conversation
std/math.d
Outdated
|
|
||
| // Find the exponent and sign | ||
| ulong msb = vl[MANTISSA_MSB]; | ||
| ulong lsb = vl[MANTISSA_LSB]; |
There was a problem hiding this comment.
I realize you're just copying the names used above in the ieeeDouble section, but these really should be named something else like hi and lo.
msb generally stands for "Most Significant Byte" (or Bit), and lsb for "Least Significant Byte" (or Bit). Using that acronym for 64-bit values (quad words, I think, in Intel terminology?) is confusing.
094724c to
3ea49b2
Compare
std/math.d
Outdated
| ulong hi = vl[MANTISSA_MSB]; | ||
| ulong lo = vl[MANTISSA_LSB]; | ||
| int exp = cast(int)((hi >> EXPSHIFT_ULONG) & F.EXPMASK) - F.EXPBIAS; | ||
| int sign = cast(int)(lo >> 63); |
There was a problem hiding this comment.
This should be:
ulong hi = vl[MANTISSA_MSB];
int exp = cast(int)((hi >> EXPSHIFT_ULONG) & F.EXPMASK) - F.EXPBIAS;
int sign = cast(int)(hi >> 63);The sign bit is in the hi part, which in turn means that you only actually need the lo part one place:
else
{
const lo = vl[MANTISSA_LSB];
result = (cast(long) hi << (exp - EXPSHIFT_ULONG)) | (lo >> (MANTISSE - exp));
}This is one of the missing functions for 128-bit reals.
|
|
||
| if (exp < 0) | ||
| result = 0; | ||
| else if (exp <= 48) |
There was a problem hiding this comment.
How about else if (exp <= EXPSHIFT_ULONG) ?
|
This PR seems OK to me now, pending @9il 's approval. |
|
I would like @redstar to reorganize this function to template (we should do it for all std.math). |
|
@9il I think we should plan on doing a clean-sheet Either way though, that can be done in a separate PR, yes? |
There is no significant problems with backwards compatibility for math functions, std.math would be upgraded step-by-step.
I would like to see the template version in this PR because |
|
32bit and 64bit should be converted to 64bit version |
Would it be worthwhile for me to try and turn this proof-of-concept I did a while ago into a real pull request? #3598 (comment) I think part of the problem with |
This should be extended instead of replaced. My bad. Current |
Check out |
|
@tsbockman Yes, we should have a |
|
But this is big work |
Indeed. I think it's time to just bite the bullet and do it, though, as otherwise we'll waste a lot of time refactoring |
In the same time you may port only few functions, so we can make a tests and review. |
Yeah I wouldn't try to do everything in one go. The first step is just to get the prerequisites, like |
| ulong* vl = cast(ulong*)(&x); | ||
|
|
||
| enum EXPSHIFT_ULONG = 48; | ||
| enum MANTISSE = real.mant_dig - 1; |
There was a problem hiding this comment.
Are these strictly necessary? I don't think anyone would mind if you just use the numbers directly in the implementation, as they are very specific to this function.
The MANTISSE should always be 112, no?
|
Logic of the 128-bit implementation looks sound to me. I would expect this to pass our current tests on lrint. |
|
Ping @redstar - do you have time to "templatize" ? |
Waiting for response to my comments would be one. |
| { | ||
| // It is left implementation defined when the number is too large | ||
| // to fit in a 64bit long. | ||
| return cast(long) x; |
There was a problem hiding this comment.
sorry for the dumb question, but isn't there a chance that if we (will) have 128-bit floats, we might see 128-bit integers too?
There was a problem hiding this comment.
128 bit floats are reality on Power64 I think
There was a problem hiding this comment.
so this function should return cent then?
There was a problem hiding this comment.
No, the changes so far just moved errors relating to cent out of the parser and into the semantic pass.
There was a problem hiding this comment.
so this function should return
centthen?
No - it should return long for now, to be compatible with algorithms that depend on the existing hard-coded return type.
Long-term, all these overly-similar rounding functions - round(), rint(), lrint(), and nearbyint() - could be replaced by a single template function. One of the template parameters can be the return type, allowing round!long() to directly replace lrint(). round!cent() would be supported as well.
|
Eight months of inactivity from the author. Closing. @redstar Please reopen if you decide to come back to this. |
This is one of the missing functions for 128-bit reals.