Skip to content

Commit 01e9740

Browse files
committed
Tweaks for Gnumeric and Xls
1 parent 3a6009d commit 01e9740

File tree

8 files changed

+94
-17
lines changed

8 files changed

+94
-17
lines changed

src/PhpSpreadsheet/Calculation/MathTrig/Ceiling.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public static function math(mixed $number, mixed $significance = null, $mode = 0
8989
}
9090
if ($checkSigns) {
9191
if (($number > 0 && $significance < 0) || ($number < 0 && $significance > 0)) {
92-
return ExcelError::VALUE();
92+
return ExcelError::NAN();
9393
}
9494
}
9595
if (self::ceilingMathTest((float) $significance, (float) $number, (int) $mode)) {
@@ -170,7 +170,12 @@ private static function argumentsOk(float $number, float $significance): float|s
170170
if (empty($number * $significance)) {
171171
return 0.0;
172172
}
173-
if (Helpers::returnSign($number) == Helpers::returnSign($significance)) {
173+
$signSig = Helpers::returnSign($significance);
174+
$signNum = Helpers::returnSign($number);
175+
if (
176+
($signSig === 1 && ($signNum === 1 || Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC))
177+
|| ($signSig === -1 && $signNum === -1)
178+
) {
174179
return ceil($number / $significance) * $significance;
175180
}
176181

src/PhpSpreadsheet/Calculation/MathTrig/Floor.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public static function math(mixed $number, mixed $significance = null, mixed $mo
9494
}
9595
if ($checkSigns) {
9696
if (($number > 0 && $significance < 0) || ($number < 0 && $significance > 0)) {
97-
return ExcelError::VALUE();
97+
return ExcelError::NAN();
9898
}
9999
}
100100

@@ -210,10 +210,12 @@ private static function argumentsOk(float $number, float $significance): string|
210210
if ($number == 0.0) {
211211
return 0.0;
212212
}
213-
if (Helpers::returnSign($significance) == 1) {
214-
return floor($number / $significance) * $significance;
215-
}
216-
if (Helpers::returnSign($number) == -1 && Helpers::returnSign($significance) == -1) {
213+
$signSig = Helpers::returnSign($significance);
214+
$signNum = Helpers::returnSign($number);
215+
if (
216+
($signSig === 1 && ($signNum === 1 || Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC))
217+
|| ($signNum === -1 && $signSig === -1)
218+
) {
217219
return floor($number / $significance) * $significance;
218220
}
219221

src/PhpSpreadsheet/Writer/Xls/Parser.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,11 @@ class Parser
410410
'FISHER' => [283, 1, 1, 0],
411411
'FISHERINV' => [284, 1, 1, 0],
412412
'FLOOR' => [285, 2, 1, 0],
413+
'FLOOR.XCL' => [285, 2, 1, 0],
413414
'GAMMADIST' => [286, 4, 1, 0],
414415
'GAMMAINV' => [287, 3, 1, 0],
415416
'CEILING' => [288, 2, 1, 0],
417+
'CEILING.XCL' => [288, 2, 1, 0],
416418
'HYPGEOMDIST' => [289, 4, 1, 0],
417419
'LOGNORMDIST' => [290, 3, 1, 0],
418420
'LOGINV' => [291, 3, 1, 0],

tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingTest.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
66

77
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
8+
use PHPUnit\Framework\Attributes\DataProvider;
89

910
class CeilingTest extends AllSetupTeardown
1011
{
11-
#[\PHPUnit\Framework\Attributes\DataProvider('providerCEILING')]
12+
#[DataProvider('providerCEILING')]
1213
public function testCEILING(mixed $expectedResult, string $formula): void
1314
{
1415
$this->mightHaveException($expectedResult);
@@ -27,6 +28,24 @@ public static function providerCEILING(): array
2728
return require 'tests/data/Calculation/MathTrig/CEILING.php';
2829
}
2930

31+
public function testCEILINGGnumericClashingSigns(): void
32+
{
33+
self::setGnumeric();
34+
$sheet = $this->getSheet();
35+
$sheet->getCell('A1')->setValue('=CEILING(17,8)');
36+
$result = $sheet->getCell('A1')->getCalculatedValue();
37+
self::assertEqualsWithDelta(24, $result, 1E-12);
38+
$sheet->getCell('A2')->setValue('=CEILING(-17,-8)');
39+
$result = $sheet->getCell('A2')->getCalculatedValue();
40+
self::assertEqualsWithDelta(-24, $result, 1E-12);
41+
$sheet->getCell('A3')->setValue('=CEILING(17,-8)');
42+
$result = $sheet->getCell('A3')->getCalculatedValue();
43+
self::assertSame('#NUM!', $result);
44+
$sheet->getCell('A4')->setValue('=CEILING(-17,8)');
45+
$result = $sheet->getCell('A4')->getCalculatedValue();
46+
self::assertSame('#NUM!', $result);
47+
}
48+
3049
public function testCEILINGGnumeric1Arg(): void
3150
{
3251
self::setGnumeric();
@@ -54,7 +73,7 @@ public function testCEILINGExcel1Arg(): void
5473
self::assertEqualsWithDelta(6, $result, 1E-12);
5574
}
5675

57-
#[\PHPUnit\Framework\Attributes\DataProvider('providerCeilingArray')]
76+
#[DataProvider('providerCeilingArray')]
5877
public function testCeilingArray(array $expectedResult, string $argument1, string $argument2): void
5978
{
6079
$calculation = Calculation::getInstance();

tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorTest.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
66

77
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
8+
use PHPUnit\Framework\Attributes\DataProvider;
89

910
class FloorTest extends AllSetupTeardown
1011
{
11-
#[\PHPUnit\Framework\Attributes\DataProvider('providerFLOOR')]
12+
#[DataProvider('providerFLOOR')]
1213
public function testFLOOR(mixed $expectedResult, string $formula): void
1314
{
1415
$this->mightHaveException($expectedResult);
@@ -27,6 +28,24 @@ public static function providerFLOOR(): array
2728
return require 'tests/data/Calculation/MathTrig/FLOOR.php';
2829
}
2930

31+
public function testFLOORGnumericClashingSigns(): void
32+
{
33+
self::setGnumeric();
34+
$sheet = $this->getSheet();
35+
$sheet->getCell('A1')->setValue('=FLOOR(17,8)');
36+
$result = $sheet->getCell('A1')->getCalculatedValue();
37+
self::assertEqualsWithDelta(16, $result, 1E-12);
38+
$sheet->getCell('A2')->setValue('=FLOOR(-17,-8)');
39+
$result = $sheet->getCell('A2')->getCalculatedValue();
40+
self::assertEqualsWithDelta(-16, $result, 1E-12);
41+
$sheet->getCell('A3')->setValue('=FLOOR(17,-8)');
42+
$result = $sheet->getCell('A3')->getCalculatedValue();
43+
self::assertSame('#NUM!', $result);
44+
$sheet->getCell('A4')->setValue('=FLOOR(-17,8)');
45+
$result = $sheet->getCell('A4')->getCalculatedValue();
46+
self::assertSame('#NUM!', $result);
47+
}
48+
3049
public function testFLOORGnumeric1Arg(): void
3150
{
3251
self::setGnumeric();
@@ -54,7 +73,7 @@ public function testFLOORExcel1Arg(): void
5473
self::assertEqualsWithDelta(5, $result, 1E-12);
5574
}
5675

57-
#[\PHPUnit\Framework\Attributes\DataProvider('providerFloorArray')]
76+
#[DataProvider('providerFloorArray')]
5877
public function testFloorArray(array $expectedResult, string $argument1, string $argument2): void
5978
{
6079
$calculation = Calculation::getInstance();

tests/PhpSpreadsheetTests/Reader/Ods/CeilingFloorTest.php

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods;
66

77
use PhpOffice\PhpSpreadsheet\Reader\Ods as OdsReader;
8+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
89
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
910

1011
class CeilingFloorTest extends AbstractFunctional
@@ -49,8 +50,8 @@ public function testReadAndWriteOds(): void
4950
"Error in cell $key"
5051
);
5152
}
52-
self::assertSame('#VALUE!', $oldSheet->getCell('E1')->getCalculatedValue());
53-
self::assertSame('#VALUE!', $oldSheet->getCell('F1')->getCalculatedValue());
53+
self::assertSame('#NUM!', $oldSheet->getCell('E1')->getCalculatedValue());
54+
self::assertSame('#NUM!', $oldSheet->getCell('F1')->getCalculatedValue());
5455

5556
$spreadsheet = $this->writeAndReload($spreadsheetOld, 'Ods');
5657
$spreadsheetOld->disconnectWorksheets();
@@ -62,8 +63,8 @@ public function testReadAndWriteOds(): void
6263
"Error in cell $key"
6364
);
6465
}
65-
self::assertSame('#VALUE!', $sheet->getCell('E1')->getCalculatedValue());
66-
self::assertSame('#VALUE!', $sheet->getCell('F1')->getCalculatedValue());
66+
self::assertSame('#NUM!', $sheet->getCell('E1')->getCalculatedValue());
67+
self::assertSame('#NUM!', $sheet->getCell('F1')->getCalculatedValue());
6768

6869
$spreadsheet->disconnectWorksheets();
6970
}
@@ -88,4 +89,32 @@ public function testReadAndWriteXlsx(): void
8889

8990
$spreadsheet->disconnectWorksheets();
9091
}
92+
93+
public function testWriteXcl(): void
94+
{
95+
$spreadsheet = new Spreadsheet();
96+
$sheet = $spreadsheet->getActiveSheet();
97+
$sheet->getCell('A1')->setValue('=CEILING.XCL(17.8,8)');
98+
$sheet->getCell('B1')->setValue('=FLOOR.XCL(17.8,8)');
99+
100+
$spreadsheetOds = $this->writeAndReload($spreadsheet, 'Ods');
101+
$sheetOds = $spreadsheetOds->getActiveSheet();
102+
self::assertSame('=CEILING(17.8,8)', $sheetOds->getCell('A1')->getValue());
103+
self::assertSame('=FLOOR(17.8,8)', $sheetOds->getCell('B1')->getValue());
104+
$spreadsheetOds->disconnectWorksheets();
105+
106+
$spreadsheetXlsx = $this->writeAndReload($spreadsheet, 'Xlsx');
107+
$sheetXlsx = $spreadsheetXlsx->getActiveSheet();
108+
self::assertSame('=CEILING(17.8,8)', $sheetXlsx->getCell('A1')->getValue());
109+
self::assertSame('=FLOOR(17.8,8)', $sheetXlsx->getCell('B1')->getValue());
110+
$spreadsheetXlsx->disconnectWorksheets();
111+
112+
$spreadsheetXls = $this->writeAndReload($spreadsheet, 'Xls');
113+
$sheetXls = $spreadsheetXls->getActiveSheet();
114+
self::assertSame('=CEILING(17.8,8)', $sheetXls->getCell('A1')->getValue());
115+
self::assertSame('=FLOOR(17.8,8)', $sheetXls->getCell('B1')->getValue());
116+
$spreadsheetXls->disconnectWorksheets();
117+
118+
$spreadsheet->disconnectWorksheets();
119+
}
91120
}

tests/data/Calculation/MathTrig/CEILING.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
[0.0, '8, 0'],
1212
[9.0, '8, 1.5'],
1313
['#NUM!', '8, -1.5'],
14-
['#NUM!', '-8, 1.5'],
14+
'changed with pr 4466 #1' => [-7.5, '-8, 1.5'],
1515
[-9.0, '-8, -1.5'],
1616
[8.3, '8.26, 0.05'],
1717
[2.35, '2.341, 0.05'],
@@ -23,7 +23,7 @@
2323
[210.70, '210.67, 0.05'],
2424
[210.65, '210.63, 0.05'],
2525
[4.0, '2.98, 2'],
26-
['#NUM!', '-2.98, 2'],
26+
'changed with pr 4466 #2' => [-2, '-2.98, 2'],
2727
[-5.0, '-4.5, -1'],
2828
[0, ',1'],
2929
[0, 'false,1'],

tests/data/Calculation/MathTrig/FLOOR.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
[-4, '-2.5, 2'],
99
[0.0, '0.0, 1'],
1010
['#NUM!', '2.5, -2'],
11+
[-4, '-2.5, 2'],
1112
['#DIV/0!', '123.456, 0'],
1213
[1.5, '1.5, 0.1'],
1314
[0.23, '0.234, 0.01'],

0 commit comments

Comments
 (0)