diff --git a/phpunit/code/big-numeric/decimal-int-operand.php b/phpunit/code/big-numeric/decimal-int-operand.php new file mode 100644 index 00000000..06bb2c41 --- /dev/null +++ b/phpunit/code/big-numeric/decimal-int-operand.php @@ -0,0 +1,22 @@ +toString(); +} + +function multiplyDecimalByVar($factor): string +{ + $value = std::decimal('123.456'); + $value = $value * $factor; + return $value->toString(); +} + +function main(): void +{ + echo multiplyDecimalByInt(1000), "\n"; + echo multiplyDecimalByVar(1000), "\n"; +} diff --git a/phpunit/src/BigNumericValidationTest.php b/phpunit/src/BigNumericValidationTest.php index e02aae0e..95841307 100644 --- a/phpunit/src/BigNumericValidationTest.php +++ b/phpunit/src/BigNumericValidationTest.php @@ -2,6 +2,31 @@ class BigNumericValidationTest extends \BaseTest { + public function testDecimalIntegerOperandDoesNotConvertThroughString(): void + { + global $translator; + $compiler = \TypePhp\CompilerTest::create(ROOT_PATH); + $translator = $compiler; + $testFile = __DIR__ . '/../code/big-numeric/decimal-int-operand.php'; + $compiler->addFiles([$testFile]); + $compiler->prepareFile($testFile); + $cppFile = $compiler->convertFile($testFile); + $cpp = file_get_contents($cppFile); + + $this->assertStringContainsString( + 'php::Decimal::mul(value, php::toDecimal(1000L))', + $cpp, + ); + $this->assertStringNotContainsString( + 'php::toDecimal(php::toString(1000L))', + $cpp, + ); + $this->assertStringContainsString( + 'php::Decimal::mul(value, factor)', + $cpp, + ); + } + public function testDecimalPowerOperatorIsRejected(): void { $this->exec("Operator '**' is not supported for Decimal or BigFloat", 'big-numeric/decimal-pow-operator.php'); diff --git a/src/Parser/TypeConversionTrait.php b/src/Parser/TypeConversionTrait.php index 1180e05d..be20056a 100644 --- a/src/Parser/TypeConversionTrait.php +++ b/src/Parser/TypeConversionTrait.php @@ -85,7 +85,7 @@ trait TypeConversionTrait return 'php::toDecimal(php::toString(' . $expr . '))'; } if ($fromType === Type::INT) { - return 'php::toDecimal(php::toString(' . $expr . '))'; + return 'php::toDecimal(' . $expr . ')'; } if ($fromType === Type::BIGINT) { return 'php::toDecimal(php::BigInt::toString(' . $expr . '))'; diff --git a/tests/compiler/decimal/int-operand-without-string-conversion.phpt b/tests/compiler/decimal/int-operand-without-string-conversion.phpt new file mode 100644 index 00000000..8e71685f --- /dev/null +++ b/tests/compiler/decimal/int-operand-without-string-conversion.phpt @@ -0,0 +1,22 @@ +--TEST-- +Decimal multiplication accepts Int and dynamically typed Int operands +--FILE-- +toString(); +} + +function main(): void +{ + $value = std::decimal('123.456'); + echo ($value * 1000)->toString(), "\n"; + echo multiplyDecimal(1000), "\n"; +} +?> +--EXPECT-- +123456.000 +123456.000