Почему этот код Java ведет себя иначе, чем этот код C? - PullRequest
0 голосов
/ 15 декабря 2018

Длинная история, как я сюда попал;включает компилятор Brainfuck to C и компилятор байт-кода Brainfuck to JVM ... кажется неуместным.Код Brainfuck, о котором идет речь, выглядит следующим образом:

>-[[<+>>>-<-<+]>]

У меня есть следующий код C:

#include <stdlib.h>
#include <stdio.h>

typedef unsigned char u8;

void m1();
void m2();

u8 *dp;

int main() {
    dp = (u8*) calloc(30000, sizeof(u8));

    dp += 1;
    *dp -= 1;
    while(*dp) {
        m1();
    }

    return 0;
}

void m1() {
    while(*dp) {
        m2();
    }
    dp += 1;
}

void m2() {
    dp -= 1;
    *dp += 1;

    dp += 3;
    *dp -= 1;

    dp -= 1;
    *dp -= 1;

    dp -= 1;
    *dp += 1;
}

Этот код заканчивается.

У меня есть Javaкод:

public class test {
    public static void main(String[] args) {
        new test().run();
    }

    int[] tape = new int[30000];
    int dp = 0;

    void adjust(int n) {
        tape[dp] += n;
        if(tape[dp] < 0) tape[dp] += 255;
        if(tape[dp] > 255) tape[dp] -= 255;
    }

    void run() {
        dp += 1;
        adjust(-1);
        while(tape[dp] != 0) {
            m1();
        }
    }

    void m1() {
        while(tape[dp] != 0) {
            m2();
        }
        dp += 1;
    }

    void m2() {
        dp -= 1;
        adjust(1);

        dp += 3;
        adjust(-1);

        dp -= 1;
        adjust(-1);

        dp -= 1;
        adjust(1);
    }
}

Не заканчивается.

Почему эти, казалось бы, эквивалентные программы ведут себя по-разному?Должно быть, я упускаю что-то очевидное?

1 Ответ

0 голосов
/ 15 декабря 2018

Эти коды не равны:

  1. Версия C выделяет байтовый массив, где как Java - целочисленный массив
  2. Версия C не выполняет фиксацию элементов массива, как Java делает

Таким образом, в Java вы должны вместо этого создать байтовый массив:

byte[] tape = new byte[30000];

И удалить ограничение в функции Adjust ():

 // if(tape[dp] < 0) tape[dp] += 255;
 // if(tape[dp] > 255) tape[dp] -= 255;

Тогда версия Java также завершается

ИЛИ , если вы хотите сохранить массив integer - тогда вы должны изменить правила переполнения / опустошения:

 if(tape[dp] < 0) tape[dp] = 256-Math.abs(tape[dp]) % 256;
 if(tape[dp] > 255) tape[dp] = tape[dp] % 256;

, потому что вы их не реализовалиправо

...