Skip to content

Commit 8366cb8

Browse files
authored
Merge pull request #156 from php-java/add-new-math-library
Add math library for calculating big numbers
2 parents 2710860 + 81fd390 commit 8366cb8

45 files changed

Lines changed: 437 additions & 524 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README-ja.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -414,14 +414,16 @@ public static void main(java.lang.String[])
414414
- **OPERANDS** はオペランドスタック上のアイテムを表示します。
415415
- **LOCAL STORAGE** はローカルストレージに格納されているアイテムの数を表示します。
416416

417-
## PHP における問題
418-
- **問題 1** PHP は Java と異なるため、巨大な数字を計算することができません。
419-
しかし、 PHPJava は `bcmath` 関数や `gmp` 関数を使って、できる限り、計算を試みようとします。
420-
したがって、 PHPJava の返す値は `string` であったり、 `int` であったり、またはその他の型である可能性があります。
421-
そのため、 `string` として基本的に扱うことを推奨します。
422417

423-
- **問題 2** PHPJava は Java とは異なるため、完全に Java の型をカバーしていません。
424-
また、以下はカバーしている範囲の型の比較表です。
418+
## 大きな数字の計算について
419+
- PHP は通常、 Java における long 型や double 型といった大きな値の計算を行うことができません。
420+
PHPJava ではそれらをカバーするために数値計算用ライブラリを使用します。
421+
それらは、 下記の Java の型でラップされて使用されます。
422+
そのため、数値をPHP側で取り扱う場合は、 string 型にキャストすることを推奨します。
423+
また、通常の 64bit 版 PHP で計算できる範囲については、PHP の四則演算を使用して計算を行います。
424+
425+
## Java の型
426+
- 下記はJava と PHPJava の型の比較表です。
425427

426428
| Java | PHPJava |
427429
|:-----|:--------|
@@ -435,9 +437,6 @@ public static void main(java.lang.String[])
435437
| float | \PHPJava\Kernel\Types\\_Float (`__toString` を含む) |
436438
| double | \PHPJava\Kernel\Types\\_Double (`__toString` を含む) |
437439

438-
- **問題 3** PHPJava は `double``float` などの浮動小数点の巨大な数字の計算をすることができません。
439-
なぜなら、 `gmp_pow` 関数はマイナス指数 (たとえば -1 乗や -2 乗など) を扱えないためです。そのため代替としてビルトインされている `pow` を使用しています。
440-
441440
## Run Kotlin on the PHPJava
442441
## Kotlin を PHPJava で動かす。
443442
Kotlin を PHPJava で動かしたいですか?

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,15 @@ public static void main(java.lang.String[])
416416
- **OPERANDS** shows the stacked items on memory.
417417
- **LOCAL STORAGE** shows the stacked items on a method.
418418

419-
## PHP problems
420-
- **Problem 1:** PHP cannot calculate big numbers because PHP is different from Java.
421-
But PHPJava uses `bcmath` functions and `gmp` functions to a certain extent to cover such calculations.
422-
Therefore, PHPJava returns a mixed value and we recommend to cast them to `string` on PHPJava.
423-
424-
- **Problem 2:** PHPJava cannot completely cover Java types because PHP is different from Java.
425-
The comparison table of Java and PHPJava is shown below:
419+
## About big number calculation
420+
- In normally, PHP cannot calculate big numbers as such as `long` and `double` types.
421+
But, PHPJava uses external `Math` library for covering above problems.
422+
And, PHPJava to use Java's type as below comparison table.
423+
Therefore, we recommend to cast them to `string` on PHPJava.
424+
And, if it can be calculated with 64-bitPHP, PHPJava uses PHP's arithmetic operations.
425+
426+
## Types of Java
427+
- The comparison table of Java and PHPJava is shown below:
426428

427429
| Java | PHPJava |
428430
|:-----|:--------|
@@ -436,8 +438,6 @@ public static void main(java.lang.String[])
436438
| float | \PHPJava\Kernel\Types\\_Float (including `__toString`) |
437439
| double | \PHPJava\Kernel\Types\\_Double (including `__toString`) |
438440

439-
- **Problem 3:** PHPJava cannot calculate big number of `double` and `float` because `gmp_pow` cannot calculate negative exponents. So, PHPJava uses built-in function `pow`.
440-
441441
## Run Kotlin on the PHPJava
442442
Do you wanna run Kotlin on the PHPJava? Are you serious?
443443
Haha, yes, you can, but this feature is currently experimental.

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "JVM emulator by PHP",
44
"type": "library",
55
"license": "MIT",
6-
"version": "0.0.7.4-dev",
6+
"version": "0.0.7.5-dev",
77
"authors": [
88
{
99
"name": "memory"
@@ -18,7 +18,8 @@
1818
"monolog/monolog": "^1.24",
1919
"gabrielelana/byte-units": "^0.5.0",
2020
"symfony/console": "^4.2",
21-
"phpdocumentor/reflection-docblock": "^4.3"
21+
"phpdocumentor/reflection-docblock": "^4.3",
22+
"brick/math": "^0.8.8"
2223
},
2324
"autoload": {
2425
"psr-4": {
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
11
<?php
22
namespace PHPJava\Core\JVM\Validations;
33

4-
use PHPJava\Utilities\BinaryTool;
5-
64
class MagicByte implements ValidatorInterface
75
{
8-
private const CAFEBABE = 'CAFEBABE';
6+
private const CAFEBABE = 0xCAFEBABE;
97
private $magicByte;
108

119
public function __construct($magicByte)
1210
{
13-
$this->magicByte = $magicByte;
11+
$this->magicByte = (int) $magicByte;
1412
}
1513

1614
public function isValid(): bool
1715
{
18-
return static::CAFEBABE === BinaryTool::toHex($this->magicByte ?? null);
16+
return static::CAFEBABE === $this->magicByte ?? 0;
1917
}
2018
}

src/Core/PHPJava.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ final class PHPJava
1212
/**
1313
* As same as composer version.
1414
*/
15-
const VERSION = 0x000074;
15+
const VERSION = 0x000075;
1616
}

src/Kernel/Mnemonics/_dadd.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22
namespace PHPJava\Kernel\Mnemonics;
33

4+
use Brick\Math\BigDecimal;
45
use PHPJava\Kernel\Types\_Double;
5-
use PHPJava\Utilities\BinaryTool;
66
use PHPJava\Utilities\Extractor;
77

88
final class _dadd implements OperationInterface
@@ -12,16 +12,12 @@ final class _dadd implements OperationInterface
1212

1313
public function execute(): void
1414
{
15-
$rightValue = $this->popFromOperandStack();
16-
$leftValue = $this->popFromOperandStack();
15+
$value2 = Extractor::getRealValue($this->popFromOperandStack());
16+
$value1 = Extractor::getRealValue($this->popFromOperandStack());
1717

18-
$this->pushToOperandStack(
19-
_Double::get(
20-
BinaryTool::add(
21-
Extractor::getRealValue($leftValue),
22-
Extractor::getRealValue($rightValue)
23-
)
24-
)
25-
);
18+
$result = (string) BigDecimal::of($value1)
19+
->plus(BigDecimal::of($value2));
20+
21+
$this->pushToOperandStack(_Double::get($result));
2622
}
2723
}

src/Kernel/Mnemonics/_ddiv.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22
namespace PHPJava\Kernel\Mnemonics;
33

4+
use Brick\Math\BigDecimal;
45
use PHPJava\Kernel\Types\_Double;
5-
use PHPJava\Utilities\BinaryTool;
66
use PHPJava\Utilities\Extractor;
77

88
final class _ddiv implements OperationInterface
@@ -12,16 +12,12 @@ final class _ddiv implements OperationInterface
1212

1313
public function execute(): void
1414
{
15-
$value2 = $this->popFromOperandStack();
16-
$value1 = $this->popFromOperandStack();
15+
$value2 = Extractor::getRealValue($this->popFromOperandStack());
16+
$value1 = Extractor::getRealValue($this->popFromOperandStack());
1717

18-
$this->pushToOperandStack(
19-
_Double::get(
20-
BinaryTool::div(
21-
Extractor::getRealValue($value1),
22-
Extractor::getRealValue($value2)
23-
)
24-
)
25-
);
18+
$result = (string) BigDecimal::of($value1)
19+
->minus(BigDecimal::of($value2));
20+
21+
$this->pushToOperandStack(_Double::get($result));
2622
}
2723
}

src/Kernel/Mnemonics/_dmul.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22
namespace PHPJava\Kernel\Mnemonics;
33

4+
use Brick\Math\BigDecimal;
45
use PHPJava\Kernel\Types\_Double;
5-
use PHPJava\Utilities\BinaryTool;
66
use PHPJava\Utilities\Extractor;
77

88
final class _dmul implements OperationInterface
@@ -12,16 +12,12 @@ final class _dmul implements OperationInterface
1212

1313
public function execute(): void
1414
{
15-
$rightValue = $this->popFromOperandStack();
16-
$leftValue = $this->popFromOperandStack();
15+
$value2 = Extractor::getRealValue($this->popFromOperandStack());
16+
$value1 = Extractor::getRealValue($this->popFromOperandStack());
1717

18-
$this->pushToOperandStack(
19-
_Double::get(
20-
BinaryTool::multiply(
21-
Extractor::getRealValue($leftValue),
22-
Extractor::getRealValue($rightValue)
23-
)
24-
)
25-
);
18+
$result = (string) BigDecimal::of($value1)
19+
->multipliedBy(BigDecimal::of($value2));
20+
21+
$this->pushToOperandStack(_Double::get($result));
2622
}
2723
}

src/Kernel/Mnemonics/_dneg.php

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22
namespace PHPJava\Kernel\Mnemonics;
33

4+
use Brick\Math\BigDecimal;
45
use PHPJava\Kernel\Types\_Double;
5-
use PHPJava\Utilities\BinaryTool;
66
use PHPJava\Utilities\Extractor;
77

88
final class _dneg implements OperationInterface
@@ -16,10 +16,9 @@ public function execute(): void
1616
$this->popFromOperandStack()
1717
);
1818

19-
$this->pushToOperandStack(
20-
_Double::get(
21-
BinaryTool::negate($value)
22-
)
23-
);
19+
$result = (string) BigDecimal::of($value)
20+
->multipliedBy(BigDecimal::of(-1));
21+
22+
$this->pushToOperandStack(_Double::get($result));
2423
}
2524
}

src/Kernel/Mnemonics/_dsub.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22
namespace PHPJava\Kernel\Mnemonics;
33

4+
use Brick\Math\BigDecimal;
45
use PHPJava\Kernel\Types\_Double;
5-
use PHPJava\Utilities\BinaryTool;
66
use PHPJava\Utilities\Extractor;
77

88
final class _dsub implements OperationInterface
@@ -12,16 +12,12 @@ final class _dsub implements OperationInterface
1212

1313
public function execute(): void
1414
{
15-
$rightValue = $this->popFromOperandStack();
16-
$leftValue = $this->popFromOperandStack();
15+
$value2 = Extractor::getRealValue($this->popFromOperandStack());
16+
$value1 = Extractor::getRealValue($this->popFromOperandStack());
1717

18-
$this->pushToOperandStack(
19-
_Double::get(
20-
BinaryTool::sub(
21-
Extractor::getRealValue($leftValue),
22-
Extractor::getRealValue($rightValue)
23-
)
24-
)
25-
);
18+
$result = (string) BigDecimal::of($value1)
19+
->minus(BigDecimal::of($value2));
20+
21+
$this->pushToOperandStack(_Double::get($result));
2622
}
2723
}

0 commit comments

Comments
 (0)