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
add std.int128 a 128 bit integer arithmetic type #8426
Conversation
Thanks for your pull request, @WalterBright! Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + phobos#8426" |
I think a generic arbitrary-fixed-size integer type would be a better addition. An implementation exists here: |
For fellow under-a-rock-dwellers, this exposes |
Blocked by dlang/druntime#3794 |
Is there a link to centralized discussion? My immediate question is that from the Druntime pull requests I got the impression that |
std/int128.d
Outdated
op == "*" || op == "/" || op == "%" || | ||
op == "&" || op == "|" || op == "^") | ||
{ | ||
if (op == "+") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why no static if
s there ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
Will this come with support for 128-bit literals? Or will we have to wait for importC to gain int128_t support for that? |
2691839
to
11c1ad6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// ++Int128
Int128 opUnary(string op)() const
if (op == "++")
{
return Int128(inc(this.data));
}
Blocked by dlang/druntime#3795 |
this(long lo) | ||
{ | ||
data.lo = lo; | ||
data.hi = lo < 0 ? ~0L : 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
data.hi = lo >> 63
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, maybe add a constructor for ulong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear what would be faster - I prefer to leave that pattern up to the optimizer!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's also clearer imo. You're shifting in the high bits
op == "*" || op == "/" || op == "%" || | ||
op == "&" || op == "|" || op == "^") | ||
{ | ||
static if (op == "+") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why we are doing template specialization by hand?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks straightforward to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, looks more readable to find the correct specialization with something like this:
Int128 opBinary(string op : "+")(Int128 op2) const
{
return Int128(add(this.data, op2.data));
}
Shouldn't be a big deal but, also, specializing in this way would be faster for the compiler to look it up, as opposed to constraints, in which it needs to evaluate the static condition, in this case, twice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My way is easier to read (for me, anyway) as it emphasizes the commonality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also prefer the constraint in the header (whether by if
or :
isn't that important) to avoid duplication, but I allow your style if you prefer it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great addition to Phobos IMO. Two more things to do:
-Documentation unit tests are missing.
-Please add a changelog entry
EDIT: I changed my mind and rejected this PR altogether. See later.
*/ | ||
module std.int128; | ||
|
||
private import core.int128; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imports are private by default. No need for the keyword.
bool opEquals(Int128 op2) const | ||
{ | ||
return data.hi == op2.data.hi && data.lo == op2.data.lo; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does leaving this function off result in errors? I'd think the default struct comparison would work.
std/int128.d
Outdated
return data.hi == op2.data.hi && data.lo == op2.data.lo; | ||
} | ||
|
||
// +Int128 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, leave comments like this off. If the reader is so bad at D that he does not understand the function signature then he's beyond help anyway.
} | ||
} | ||
|
||
unittest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add attributes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see line 324
I don't see why this should be in Phobos versus druntime. Having 128 bit types as a library is already bizarre compared to what you get in basically any other systems programming language (even if we then special case them to use the proper compiler intrinsics i.e. the code generated at the moment is terrible), but if we really do that why would they be split across phobos and druntime? |
Thinking about that, I also think we should define a decent public interface on Another thing I'm currently thinking about wrapping |
Not really. See Having a 128 bit integer will bloat a lot of the internal data structures, that are used a lot, by 64 bits. That's pretty expensive.
Druntime provides the guts that need to be adjusted for each target. Phobos provides the user interface. std.complex is in Phobos. We also split math routines between druntime and phobos. Other languages do it as a builtin type because their metaprogramming facilities are deficient or nonexistent. Lastly, doing it in Phobos means it can be done now. |
Style sez:
but it obviously does. |
Hazarding a guess, but wouldn't that mean documented unittest? i.e
|
@ibuclaw Same error. I don't know what it wants. |
@RazvanN7 do you know what DScanner wants here? |
fd8e402
to
d113d61
Compare
|
@WalterBright The version(unittest) might confuse D-scanner. You could try putting the documented unittest right after the You can run the check locally:
|
I tried it:
No joy. I filed an issue for dscanner: In the meantime, how do I disable this check? |
There's a |
Thank you. Also, dscanner does not come with the distribution. Oh, I see why I didn't see the .dscanner.ini earlier. It has the . which hides it. What is the purpose of hiding critical files? |
I have no idea. When I started contributing to D this modus operandi was already put in place, but I would assume that, ideally, all checks would be enabled for all files, so it might be that the config file is just a stop gap solution until we reach that point. |
.dscanner.ini also explains why doing it the way std.complex didn't work, either. That's in the disable list. |
It's good that |
|
||
Cent data; /// core.int128.Cent | ||
|
||
/**************** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the right style in documentation comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used the correct style. Dscanner does not work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not about Dscanner, and you're not using the correct style. There's extra stars.
- Documentation comments should not use more than two stars /** or two pluses /++ in the header line.
(...)- Documentation comments should not have leading stars on each line.
Did that. It still fails that check. |
I tried your suggestion. It does not work.
So what about the |
We may eventually implement |
Fix Issue: #20139 add std.int128 a 128 bit integer arithmetic type
A 128 bit signed integer type.
Not done is the unsigned version.