Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ Sorry, I do not have enough time (T_T)

- Implements
- Event
- double/float calculation.
- Many built-in libraries (ex. java.lang.xxx, java.io.xxx and so on)
- etc...

Expand Down Expand Up @@ -290,11 +289,11 @@ public static void main(java.lang.String[])
- **LOCAL STORAGE** is showing stacked items on a method.

## PHP problems
- The PHP is cannot calculating big numbers because of PHP is different to the Java.
- **Problem 1:** The PHP is cannot calculating big numbers because of PHP is different to the Java.
But the PHPJava use `bcmath` functions and `gmp` functions to a certain extent to cover to calculate.
The PHPJava return valued is mixed why therefore We recommend to cast to `string` on the PHPJava.

- The PHPJava cannot cover to Java's types completely because of PHP is different to the Java.
- **Problem 2:** The PHPJava cannot cover to Java's types completely because of PHP is different to the Java.
The Java and the PHPJava comparison table is below.

|Java |PHPJava |
Expand All @@ -309,6 +308,9 @@ public static void main(java.lang.String[])
|float |\PHPJava\Kernel\Types\\_Float (including `__toString`), string, float |
|double |\PHPJava\Kernel\Types\\_Char (including `__toString`), string, float |

- **Problem 3:** The PHPJava cannot calculate big numbered `double` and `float` values because of `gmp_pow` cannot calculate negative exponents.
So the PHPJava use built-in functions which is `pow`.

## Run unit tests

- PHPUnit test is below.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "JVM emulator by PHP",
"type": "library",
"license": "MIT",
"version": "0.0.4.2-dev",
"version": "0.0.4.5-dev",
"authors": [
{
"name": "memory"
Expand Down
2 changes: 1 addition & 1 deletion src/Kernel/Mnemonics/_dadd.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ public function execute(): void
$value1 = $this->getStack();
$value2 = $this->getStack();

$this->pushStack(BinaryTool::add($value1, $value2, 8));
$this->pushStack(BinaryTool::add($value1, $value2));
}
}
2 changes: 1 addition & 1 deletion src/Kernel/Mnemonics/_iadd.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ public function execute(): void
$leftValue = $this->getStack();
$rightValue = $this->getStack();

$this->pushStack(BinaryTool::add($leftValue, $rightValue, 4));
$this->pushStack(BinaryTool::add($leftValue, $rightValue));
}
}
2 changes: 1 addition & 1 deletion src/Kernel/Mnemonics/_ishl.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ public function execute(): void
$value1 = $this->getStack();
$value2 = $this->getStack();

$this->pushStack(BinaryTool::shiftLeft($value1, $value2, 4));
$this->pushStack(BinaryTool::shiftLeft($value1, $value2));
}
}
2 changes: 1 addition & 1 deletion src/Kernel/Mnemonics/_ladd.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ public function execute(): void
$value1 = $this->getStack();
$value2 = $this->getStack();

$this->pushStack(BinaryTool::add($value1, $value2, 8));
$this->pushStack(BinaryTool::add($value1, $value2));
}
}
2 changes: 1 addition & 1 deletion src/Kernel/Mnemonics/_lshl.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ public function execute(): void
$value1 = $this->getStack();
$value2 = $this->getStack();

$this->pushStack(BinaryTool::shiftLeft($value1, $value2, 8));
$this->pushStack(BinaryTool::shiftLeft($value1, $value2));
}
}
5 changes: 4 additions & 1 deletion src/Kernel/Structures/_Double.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ public function execute(): void
$this->highBytes = $this->readUnsignedInt();
$this->lowBytes = $this->readUnsignedInt();
}

public function getBytes()
{
return ($this->highBytes << 32) + $this->lowBytes;
return BinaryTool::convertDoubleToIEEE754(
($this->highBytes << 32) + $this->lowBytes
);
}
}
2 changes: 1 addition & 1 deletion src/Kernel/Structures/_Float.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ public function execute(): void
}
public function getBytes()
{
return $this->bytes;
return BinaryTool::convertFloatToIEEE754($this->bytes);
}
}
113 changes: 31 additions & 82 deletions src/Utilities/BinaryTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ final public static function toHex($data)
if (is_int($data)) {
return sprintf('%X', $data);
}

return strtoupper(base_convert($data, 10, 16));
}

Expand All @@ -18,11 +17,7 @@ final public static function reverseBits($bits)

// reverse
for ($i = 0; $i < $bitSize; $i++) {
if ($bits[$i] === '0') {
$bits[$i] = '1';
} else {
$bits[$i] = '0';
}
$bits[$i] = $bits[$i] === '0' ? '1' : '0';
}

return $bits;
Expand All @@ -36,17 +31,11 @@ final public static function addOneBit($bits)
// nop
}

if ($index === -1) {
throw new BinaryToolsException('Passed parameter was overflow');
}

$bits[$index] = '1';

for ($i = $index + 1; $i < $bitSize; $i++) {
$bits[$i] = '0';
}


return $bits;
}

Expand Down Expand Up @@ -74,14 +63,7 @@ final public static function negate($value, $bytes)
}

$convert = self::addOneBit(self::reverseBits($value));

if ($convert[0] === '1') {
$convert = '-' . base_convert($convert, 2, 10);
} else {
$convert = base_convert($convert, 2, 10);
}

return $convert;
return ($convert[0] === '1' ? '-' : '') . base_convert($convert, 2, 10);
}

final public static function multiply($value1, $value2, $bytes)
Expand All @@ -91,16 +73,13 @@ final public static function multiply($value1, $value2, $bytes)
if (function_exists('gmp_mul')) {
$a = gmp_init($value1);
$b = gmp_init($value2);

return gmp_strval(gmp_mul($a, $b));
} elseif (function_exists('bcmul')) {
return bcmul($value1, $value2);
} else {
throw new BinaryToolsException('Cannot multiply values.');
}

return $value1 * $value2;
}

final public static function add($value1, $value2, $bytes)
final public static function add($value1, $value2)
{
$value1 = (int) $value1;
$value2 = (int) $value2;
Expand All @@ -109,11 +88,8 @@ final public static function add($value1, $value2, $bytes)
$b = gmp_init($value2);

return gmp_strval(gmp_add($a, $b));
} elseif (function_exists('bcadd')) {
return bcadd($value1, $value2);
} else {
throw new BinaryToolsException('Cannot add values.');
}
return $value1 + $value2;
}

final public static function sub($value1, $value2, $bytes)
Expand All @@ -125,11 +101,8 @@ final public static function sub($value1, $value2, $bytes)
$b = gmp_init($value2);

return gmp_strval(gmp_sub($a, $b));
} elseif (function_exists('bcsub')) {
return bcsub($value1, $value2);
} else {
throw new BinaryToolsException('Cannot sub values.');
}
return $value1 - $value2;
}

final public static function div($value1, $value2, $bytes)
Expand All @@ -141,22 +114,21 @@ final public static function div($value1, $value2, $bytes)
$b = gmp_init($value2);

return gmp_strval(gmp_div($a, $b));
} elseif (function_exists('bcdiv')) {
return bcdiv($value1, $value2);
} else {
throw new BinaryToolsException('Cannot div values.');
}

return $value1 / $value2;
}

final public static function shiftLeft($value1, $value2, $bytes)
final public static function shiftLeft($value1, $value2)
{
$value1 = (int) $value1;
$value2 = (int) $value2;
$bits = base_convert($value1, 10, 2);

$bits = sprintf('%0' . ($bytes * 8) . 's', $bits . str_repeat('0', $value2));
if (function_exists('gmp_mul')) {
return gmp_strval(gmp_mul($value1, gmp_pow(2, $value2)));
}

return base_convert($bits, 2, 10);
return $value1 << $value2;
}

final public static function unsignedShiftRight($value1, $value2, $bytes)
Expand Down Expand Up @@ -188,11 +160,7 @@ final public static function orBits($value1, $value2, $bytes)

$build = '';
for ($i = 0; $i < $bytes * 8; $i++) {
if ($value1[$i] === '1' || $value2[$i] == '1') {
$build .= '1';
} else {
$build .= '0';
}
$build .= ($value1[$i] === '1' || $value2[$i] == '1') ? '1' : '0';
}

return base_convert($build, 2, 10);
Expand All @@ -207,12 +175,7 @@ final public static function xorBits($value1, $value2, $bytes)

$build = '';
for ($i = 0; $i < $bytes * 8; $i++) {
if (($value1[$i] === '1' && $value2[$i] === '0') ||
($value1[$i] === '0' && $value2[$i] === '1')) {
$build .= '1';
} else {
$build .= '0';
}
$build .= (($value1[$i] === '1' && $value2[$i] === '0') || ($value1[$i] === '0' && $value2[$i] === '1')) ? '1' : 0;
}

return base_convert($build, 2, 10);
Expand All @@ -227,41 +190,27 @@ final public static function andBits($value1, $value2, $bytes)

$build = '';
for ($i = 0; $i < $bytes * 8; $i++) {
if ($value1[$i] === '1' && $value2[$i] === '1') {
$build .= '1';
} else {
$build .= '0';
}
$build .= $value1[$i] === '1' && $value2[$i] === '1' ? '1' : '0';
}

return base_convert($build, 2, 10);
}

final public static function convertDoubleToIEEE754($doubleValue, $rounded = 8)
final public static function convertDoubleToIEEE754($doubleValue)
{
$doubleValue = sprintf('%063s', base_convert($doubleValue, 10, 2));

$sign = $doubleValue[0];
$exponent = substr($doubleValue, 1, 10);
$fraction = substr($doubleValue, 11);

// double scale
$scale = 52;

$fractionData = 0;
for ($i = 0; $i < 52; $i++) {
$fractionData = bcadd($fractionData, bcmul($fraction[$i], bcpow(2, -1 * ($i + 1), $scale), $scale), $scale);
}

// calc sign
$operand1 = -1 * $sign;

// calc fraction
$operand2 = bcadd(1, $fractionData, $scale);

// calc exponent and bias(?)
$operand3 = bcpow(2, bindec($exponent), $scale);
$bits = $doubleValue;
$s = ($bits >> 63) == 0 ? 1 : -1;
$e = ($bits >> 52) & 0x7ff;
$m = ($e == 0) ? (($bits & 0xfffffffffffff) << 1) : ($bits & 0xfffffffffffff) | 0x10000000000000;
return $s * $m * pow(2, $e - 1075);
}

return bcmul(-2, bcmul(bcmul($operand1, $operand2, $scale), $operand3, $scale), $rounded);
final public static function convertFloatToIEEE754($floatValue)
{
$bits = $floatValue;
$s = ($bits >> 31) == 0 ? 1 : -1;
$e = ($bits >> 23) & 0xff;
$m = ($e == 0) ? (($bits & 0x7fffff) << 1) : ($bits & 0x7fffff) | 0x800000;
return $s * $m * pow(2, $e - 150);
}
}