Разделение и округление в сборке - PullRequest
0 голосов
/ 10 апреля 2020

У меня есть два числа (DWORD номер_A и DWORD номер_B). Я не уверен, как go насчет деления двух, чтобы получить десятичное число, округленное до ближайшей тысячной.

(ie)

DWORD number_A 20
DWORD number_B 10

A / B = 2,00 - формат ответа, который я пытаюсь получить.

Как мне go рассказать о делении и отображении ответа, как указано выше, на ассемблере? Мы также используем библиотеку irvine, если это поможет.

1 Ответ

1 голос
/ 10 апреля 2020

Если вы хотите сделать это, используя целочисленное арифметическое c, то (метод 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 состоит в том, что они не срабатывают таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...