将公式从 Java 移植到 PHP 时出现问题

Problems porting formula from Java to PHP

我的任务是将一家小型内部公司 formula/algorithm 从 Java 移植到 PHP,并且在很大程度上取得了成功,但我显然在某处出错了,因为我从我的移植版本中得到的输出与我从 PHP 版本中得到的输出不同。我对 PHP 比较陌生,对 Java 一无所知,所以我猜我错过了两种语言在数学运算方式上的细微但关键的区别,尤其是在线使用 doublefloor() 函数。

这里是原始的 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字符串运算中charAtreturns结果为整数类型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 是一个演示。