Как мне вычислить остаток / по модулю двух чисел без оператора «%»? - PullRequest
0 голосов
/ 28 мая 2020

Например, со следующим вводом:

int num = -100
int divisor = 10
=>  -100 mod 10 = 0   (Edge-case: negative numbers as input) 

int num = 300
int divisor = -7
=>300 mod 7 = 6

Я использовал этот метод раньше, но с отрицательными числами, он не работает:

int method(int i, int div){
    return (num - divisor * (num / divisor));
}

Ожидаемый результат:

-1234, 512 ==> <302>

Фактический результат:

-1234, 512 ==> <210>

Ответы [ 3 ]

0 голосов
/ 28 мая 2020

Ваш код отлично работает с модулем и без модуля.

Они оба дают одинаковые результаты для отрицательных и положительных чисел.

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        System.out.println("Enter the Dividend : ");
        int i = scan.nextInt();
        System.out.println("\nEnter the Divisor : ");
        int div = scan.nextInt();

        System.out.println("Without modulo :Dividend: " + i + " , Divisor: " + div + ", Remainder: "  +(i - div * (i / div)));
        System.out.println("With modulo    :Dividend: " + i + " , Divisor: " + div + ", Remainder: "  +(i % div));
        System.out.println("Using abstract :Dividend: " + i + " , Divisor: " + div + ", Remainder: "  +Math.abs(i - div * (i / div)));

    }
}

Вывод:

Enter the Dividend :                                                                                                                                        
300                                                                                                                                                       
Enter the Divisor :                                                                                                                                         
-7                                                                                                                                                          
Without modulo :Dividend: 300 , Divisor: -7, Remainder: 6                                                                                                   
With module    :Dividend: 300 , Divisor: -7, Remainder: 6
Using abstract :Dividend: 300,  Divisor: -7, Remainder: 6

Enter the Dividend :                                                                                                                                          
-1234                                                                                                                                                         

Enter the Divisor :                                                                                                                                           
512                                                                                                                                                           
Without modulo :Dividend: -1234 , Divisor: 512, Remainder: -210                                                                                               
With module    :Dividend: -1234 , Divisor: 512, Remainder: -210
Using abstract :Dividend: -1234 , Divisor: 512, Remainder: 210
0 голосов
/ 28 мая 2020

Вот ваш метод.

static int method(int num, int div){
   return num - div * (num / div);
}

Он отлично работает, поскольку возвращает остаток независимо от используемых знаков, как и %. Но если вы хотите получить больше ответа positive mod, вам необходимо сделать следующее:

static int method(int num, int div){
   int mod = num - div * (num / div);
   return (mod < 0) ? mod + div : mod;
}

Из спецификации Java виртуальной машины для irem .

И значение1, и значение2 должны иметь тип int. Значения извлекаются из стека операндов. Результатом int является значение1 - (значение1 / значение2) * значение2. Результат помещается в стек операндов.

0 голосов
/ 28 мая 2020

Следующий тест доказывает, что ваша первоначальная реализация дает те же результаты, что и исходный оператор %:

static int mod(int n, int m) {
    return n - m * (n / m);
}
// test
int[][] data = {
    {100, 10}, {-100, 10}, {100, -10}, {-100, -10},
    {   5, 3}, {-  5,  3}, {  5, - 3}, {-  5, - 3}
};

Arrays.stream(data)
      .forEach(d -> System.out.printf("%s: %d %% %d = %d mod=%d%n",
               d[0]%d[1] == mod(d[0], d[1]) ? "OK" : "BAD", 
               d[0], d[1], d[0]%d[1], mod(d[0], d[1])));

Вывод:

OK: 100 % 10 = 0 mod=0
OK: -100 % 10 = 0 mod=0
OK: 100 % -10 = 0 mod=0
OK: -100 % -10 = 0 mod=0
OK: 5 % 3 = 2 mod=2
OK: -5 % 3 = -2 mod=-2
OK: 5 % -3 = 2 mod=2
OK: -5 % -3 = -2 mod=-2
...