Thread overview | ||||||
---|---|---|---|---|---|---|
|
November 21, 2016 How to muldiv in D? | ||||
---|---|---|---|---|
| ||||
Can't find a function for it. |
November 21, 2016 Re: How to muldiv in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On 11/21/2016 11:16 AM, Kagamin wrote: > Can't find a function for it. Here is a draft adapted from the following page http://stackoverflow.com/questions/14872499/is-there-an-equivalent-to-muldiv-for-linux This draft works for signed types: T mulDiv(T)(T number, T numerator, T denominator) { static if (is (T == long)) { static assert("Sorry, can't support long"); } else static if (is (T == int)) { alias InterimT = long; } else { alias InterimT = int; } InterimT ret = number; ret *= numerator; ret /= denominator; return cast(T)ret; } void main() { int number = int.max / 2; int numerator = 42; int denominator = numerator * 2; const correctResult = int.max / 4; const wrongResult = number * numerator / denominator; assert(mulDiv(number, numerator, denominator) == correctResult); assert(wrongResult != correctResult); } Ali |
November 22, 2016 Re: How to muldiv in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Yep, I need muldiv for long values on x86-64. |
November 22, 2016 Re: How to muldiv in D? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On Tuesday, 22 November 2016 at 08:54:36 UTC, Kagamin wrote:
> Yep, I need muldiv for long values on x86-64.
Quick and dirty assembler:
version(D_InlineAsm_X86_64):
long muldiv(long a, long b, long c)
{
//windows RCX, RDX, R8
//linux RDI, RSI, RDX
version(Windows)
{
asm
{
naked;
mov RAX, RCX; //RAX = a
imul RDX; //RDX:RAX = a * b
idiv R8; //RAX = a * b / c
ret;
}
}
else version(linux)
{
asm
{
naked;
mov RAX, RDI; //RAX = a;
mov R8, RDX; //R8 = b
imul RSI; //RDX:RAX = a * b
idiv R8; //RAX = a * b / c
ret;
}
}
else
static assert(0);
}
|
Copyright © 1999-2021 by the D Language Foundation