Если вы хотите сделать это с помощью целочисленной арифметики, то (метод 1):
q = A / B -- integer division ) assuming unsigned numbers, that's
r = A % B -- integer remainder ) q = eax and r = edx after a DIV
r = r * 1000
f = r / B -- also integer division/remainder, as above
r = r % B
f += ((r * 2) >= B) -- where >= returns 0 or 1
if (f > 999) { q += 1 ; f = 0 ; }
затем выведите q
, за которым следует '.', а затем 3 цифры для f
с начальными нулями, как требуется.
Вы также можете выполнить округление и дробную часть следующим образом (метод 2):
q = A / B -- as above
r = A % B
r = r * 2000
f = r / B -- result f is in half-thousandths
f = (f + 1) >> 1 -- round to nearest thousandth
if (f > 999) { q += 1 ; f = 0 ; }
В этой и предыдущей формах, если B
(очень) велико, r * 2000
(и действительно r * 1000
) может быть больше 32 бит, но это нормально, потому что DIV
справится с 64-битным делимым, при условии, что частное меньше 2^32 -- и мы знаем, что частное в этом случае меньше 2000 (или 1000).
Как отмечалось в другом месте, вы также можете сделать это (метод 3):
A = A * 1000
q = A / B
r = A % B
q += ((r * 2) >= B) -- where >= returns 0 or 1
f = q % 1000 -- alternatively, when outputting, convert f to
q = q / 1000 -- decimal and insert '.' before last 3 digits
И, как вариант (метод 4):
q = (A * 2000) / B -- again half-thousandths
q = (q + 1) >> 1 -- round to nearest thousandth
НО: деление завершится ошибкой, если A * 1000
(или A * 2000
) больше или равно B * 2^32
, потому что q
больше или равно 2^32.
Преимущество методов 1 и 2 в том, что они не сбиваются с толку таким образом.
person
Chris Hall
schedule
10.04.2020
cvtsi2sd
иdivsd
для преобразования вdouble
в регистрах XMM? felixcloutier.com/x86/cvtsi2sd - person Peter Cordes   schedule 10.04.2020