Веб-формы также получают от большей зрелости, и поддержка от третьего лица управляют поставщиками как Telerik.
gcc 4.3.2, с оптимизацией -O1 или выше, транслировал вашу функцию точно так, как вы показывали, в сборку IA32, например:
umulhi32:
pushl %ebp
movl %esp, %ebp
movl 12(%ebp), %eax
mull 8(%ebp)
movl %edx, %eax
popl %ebp
ret
Это просто выполняет одну 32-битную mull
и помещает старшие 32 бита результата (из % edx
) в возвращаемое значение.
Это то, что вы хотели, верно? Похоже, вам просто нужно включить оптимизацию вашего компилятора;) Возможно, вы могли бы подтолкнуть компилятор в правильном направлении, исключив промежуточную переменную:
unsigned int umulhi32(unsigned int x, unsigned int y)
{
return (unsigned int)(((unsigned long long)x * y)>>32);
}
На 32-битном Intel умножение влияет на два регистра вывода. То есть 64 бита полностью доступны, хотите вы этого или нет. Это просто функция от того, достаточно ли умен компилятор, чтобы воспользоваться этим.
Современные компиляторы делают удивительные вещи, поэтому я предлагаю еще поэкспериментировать с флагами оптимизации, по крайней мере на Intel. Вы можете подумать, что оптимизатор может знать, что процессор выдает 64-битное значение из 32 на 32 бит.
Тем не менее, в какой-то момент я попытался заставить компилятор использовать как по модулю, так и дивиденд в результате деления , но старый компилятор Microsoft 1998 года был недостаточно умен, чтобы понять, что одна и та же инструкция дает оба результата.
Я не думаю, что есть способ сделать это в стандартном C / C ++ лучше, чем то, что у вас уже есть. Я бы написал простую оболочку сборки, которая вернула бы желаемый результат.
Не то, чтобы вы спрашивали о Windows, а в качестве примера, хотя в Windows есть API, который звучит так, как будто он делает то, что вы хотите ( 32-битное умножение на 32-битное с получением полного 64-битного результата), он реализует умножение как макрос, который делает то, что вы делаете:
#define UInt32x32To64( a, b ) (ULONGLONG)((ULONGLONG)(DWORD)(a) * (DWORD)(b))