为什么此 Java 代码的行为与此 C 代码不同?
Why does this Java code behave differently than this C code?
长话短说我是怎么来到这里的;涉及一个 Brainfuck 到 C 编译器和一个 Brainfuck 到 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);
}
}
它不会终止。
为什么这些看似相同的程序表现不同?我一定是遗漏了一些明显的东西?
这些代码不相等:
- C 版本分配字节数组,其中 Java - 整数数组
- C 版本不像 Java 那样对数组元素进行钳制
所以在 Java 中你应该创建一个字节数组:
byte[] tape = new byte[30000];
并在 adjust() 函数中删除夹紧:
// if(tape[dp] < 0) tape[dp] += 255;
// if(tape[dp] > 255) tape[dp] -= 255;
然后Java的版本也终止了
或如果你想保留整数数组——那么你必须改变你的overflow/underflow规则:
if(tape[dp] < 0) tape[dp] = 256-Math.abs(tape[dp]) % 256;
if(tape[dp] > 255) tape[dp] = tape[dp] % 256;
因为你实施的不对
长话短说我是怎么来到这里的;涉及一个 Brainfuck 到 C 编译器和一个 Brainfuck 到 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);
}
}
它不会终止。
为什么这些看似相同的程序表现不同?我一定是遗漏了一些明显的东西?
这些代码不相等:
- C 版本分配字节数组,其中 Java - 整数数组
- C 版本不像 Java 那样对数组元素进行钳制
所以在 Java 中你应该创建一个字节数组:
byte[] tape = new byte[30000];
并在 adjust() 函数中删除夹紧:
// if(tape[dp] < 0) tape[dp] += 255;
// if(tape[dp] > 255) tape[dp] -= 255;
然后Java的版本也终止了
或如果你想保留整数数组——那么你必须改变你的overflow/underflow规则:
if(tape[dp] < 0) tape[dp] = 256-Math.abs(tape[dp]) % 256;
if(tape[dp] > 255) tape[dp] = tape[dp] % 256;
因为你实施的不对