Re: How to muldiv in D?

2016-11-22 Thread rumbu via Digitalmars-d-learn

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);
}


Re: How to muldiv in D?

2016-11-22 Thread Kagamin via Digitalmars-d-learn

Yep, I need muldiv for long values on x86-64.


Re: How to muldiv in D?

2016-11-21 Thread Ali Çehreli via Digitalmars-d-learn

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