将公式从 Java 移植到 PHP 时出现问题
Problems porting formula from Java to PHP
我的任务是将一家小型内部公司 formula/algorithm 从 Java 移植到 PHP,并且在很大程度上取得了成功,但我显然在某处出错了,因为我从我的移植版本中得到的输出与我从 PHP 版本中得到的输出不同。我对 PHP 比较陌生,对 Java 一无所知,所以我猜我错过了两种语言在数学运算方式上的细微但关键的区别,尤其是在线使用 double
和 floor()
函数。
这里是原始的 Java 代码,它需要以 F999
格式接受用户输入并生成一个四位数的输出:
String input;
String Generate() {
int charAt = (((this.input.charAt(0) * 5) * 2) - 698) + this.input.charAt(1);
int charAt2 = ((((this.input.charAt(2) * 5) * 2) + charAt) + this.input.charAt(3)) - 528;
charAt2 = ((charAt2 << 3) - charAt2) % 100;
String valueOf = String.valueOf((((((259 % charAt) % 100) * 5) * 5) * 4) + ((((charAt2 % 10) * 5) * 2) + ((int) Math.floor((double) (charAt2 / 10)))));
return valueOf.length() == 3 ? "0" + valueOf : valueOf.length() == 2 ? "00" + valueOf : valueOf.length() == 1 ? "000" + valueOf : valueOf;
}
这是我移植的 PHP 版本,目前使用字符串模拟用户输入:
$input = "F999"; # should output 2360
$charAt = ((((int) $input[0] * 5) * 2) - 698) + $input[1];
$charAt2 = (((($input[2] * 5) * 2) + $charAt) + $input[3]) - 528;
$charAt2 = (($charAt2 << 3) - $charAt2) % 100;
$valueOf = strval(((((((259 % $charAt) % 100) * 5) * 5) * 4) + (((($charAt2 % 10) * 5) * 2) + ((int) floor((double) ($charAt2 / 10))))));
if (strlen($valueOf) == 3) $valueOf = '0' . $valueOf;
elseif (strlen($valueOf) == 2) $valueOf = '00' . $valueOf;
elseif (strlen($valueOf) == 1) $valueOf = '000' . $valueOf;
return $valueOf; # currently outputs 5837
Java 源有什么我的 PHP 代码丢失了?
问题是由以下差异引起的:
- 在Java字符串运算中
charAt
returns结果为整数类型char
,是0到65535之间的无符号整数。
- 在PHP字符串索引操作
[]
returns结果为一个字符。
因此,在Javathis.input.charAt(0)
returns中得到'F'的ASCII码,即70。
PHP$input[0]
returns中的一个字符'F',不能直接转成int。因此,在 PHP 中,(int)('F')
只是 0。要获得 PHP 中符号的 ASCII 码,请使用 ord()
。例如:
$input = "F999"; # should output 2360
$charAt = (((ord($input[0]) * 5) * 2) - 698) + ord($input[1]);
$charAt2 = ((((ord($input[2]) * 5) * 2) + $charAt) + ord($input[3])) - 528;
$charAt2 = (($charAt2 << 3) - $charAt2) % 100;
$valueOf = strval(((((((259 % $charAt) % 100) * 5) * 5) * 4) + (((($charAt2 % 10) * 5) * 2) + ((int) floor((double) ($charAt2 / 10))))));
if (strlen($valueOf) == 3) $valueOf = '0' . $valueOf;
elseif (strlen($valueOf) == 2) $valueOf = '00' . $valueOf;
elseif (strlen($valueOf) == 1) $valueOf = '000' . $valueOf;
return $valueOf;
Here 是一个演示。
我的任务是将一家小型内部公司 formula/algorithm 从 Java 移植到 PHP,并且在很大程度上取得了成功,但我显然在某处出错了,因为我从我的移植版本中得到的输出与我从 PHP 版本中得到的输出不同。我对 PHP 比较陌生,对 Java 一无所知,所以我猜我错过了两种语言在数学运算方式上的细微但关键的区别,尤其是在线使用 double
和 floor()
函数。
这里是原始的 Java 代码,它需要以 F999
格式接受用户输入并生成一个四位数的输出:
String input;
String Generate() {
int charAt = (((this.input.charAt(0) * 5) * 2) - 698) + this.input.charAt(1);
int charAt2 = ((((this.input.charAt(2) * 5) * 2) + charAt) + this.input.charAt(3)) - 528;
charAt2 = ((charAt2 << 3) - charAt2) % 100;
String valueOf = String.valueOf((((((259 % charAt) % 100) * 5) * 5) * 4) + ((((charAt2 % 10) * 5) * 2) + ((int) Math.floor((double) (charAt2 / 10)))));
return valueOf.length() == 3 ? "0" + valueOf : valueOf.length() == 2 ? "00" + valueOf : valueOf.length() == 1 ? "000" + valueOf : valueOf;
}
这是我移植的 PHP 版本,目前使用字符串模拟用户输入:
$input = "F999"; # should output 2360
$charAt = ((((int) $input[0] * 5) * 2) - 698) + $input[1];
$charAt2 = (((($input[2] * 5) * 2) + $charAt) + $input[3]) - 528;
$charAt2 = (($charAt2 << 3) - $charAt2) % 100;
$valueOf = strval(((((((259 % $charAt) % 100) * 5) * 5) * 4) + (((($charAt2 % 10) * 5) * 2) + ((int) floor((double) ($charAt2 / 10))))));
if (strlen($valueOf) == 3) $valueOf = '0' . $valueOf;
elseif (strlen($valueOf) == 2) $valueOf = '00' . $valueOf;
elseif (strlen($valueOf) == 1) $valueOf = '000' . $valueOf;
return $valueOf; # currently outputs 5837
Java 源有什么我的 PHP 代码丢失了?
问题是由以下差异引起的:
- 在Java字符串运算中
charAt
returns结果为整数类型char
,是0到65535之间的无符号整数。 - 在PHP字符串索引操作
[]
returns结果为一个字符。
因此,在Javathis.input.charAt(0)
returns中得到'F'的ASCII码,即70。
PHP$input[0]
returns中的一个字符'F',不能直接转成int。因此,在 PHP 中,(int)('F')
只是 0。要获得 PHP 中符号的 ASCII 码,请使用 ord()
。例如:
$input = "F999"; # should output 2360
$charAt = (((ord($input[0]) * 5) * 2) - 698) + ord($input[1]);
$charAt2 = ((((ord($input[2]) * 5) * 2) + $charAt) + ord($input[3])) - 528;
$charAt2 = (($charAt2 << 3) - $charAt2) % 100;
$valueOf = strval(((((((259 % $charAt) % 100) * 5) * 5) * 4) + (((($charAt2 % 10) * 5) * 2) + ((int) floor((double) ($charAt2 / 10))))));
if (strlen($valueOf) == 3) $valueOf = '0' . $valueOf;
elseif (strlen($valueOf) == 2) $valueOf = '00' . $valueOf;
elseif (strlen($valueOf) == 1) $valueOf = '000' . $valueOf;
return $valueOf;
Here 是一个演示。