Skip to content

Commit 661a89b

Browse files
committed
fix Field::normalize/compare
1 parent c19c914 commit 661a89b

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

src/Field.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,10 @@ public function normalize($value)
187187
} else {
188188
throw new Exception('Must not be boolean type');
189189
}
190-
} elseif (is_scalar($value)) {
190+
} elseif (is_int($value)) {
191191
$value = (string) $value;
192+
} elseif (is_float($value)) {
193+
$value = Expression::castFloatToString($value);
192194
} else {
193195
throw new Exception('Must be scalar');
194196
}
@@ -364,7 +366,12 @@ private function getValueForCompare($value): ?string
364366
return null;
365367
}
366368

367-
return (string) $this->typecastSaveField($value, true);
369+
$res = $this->typecastSaveField($value, true);
370+
if (is_float($res)) {
371+
return Expression::castFloatToString($res);
372+
}
373+
374+
return (string) $res;
368375
}
369376

370377
/**

src/Persistence/Sql/Expression.php

+2
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,8 @@ final public static function castFloatToString(float $value): string
630630
$precisionBackup = ini_get('precision');
631631
try {
632632
// loop needed, see https://github.com/php/php-src/issues/8509
633+
// fixed precision of 17 for conversion can render unneeded decimal digits like
634+
// 0.40000000000000002 although 0.4 is enough to represent such float number exactly
633635
for ($i = 1; $i <= 17; ++$i) {
634636
ini_set('precision', (string) $i);
635637
$res = (string) $value;

tests/TypecastingTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ public function testType(): void
109109
unset($duplicate['id']);
110110

111111
$this->assertEquals($first, $duplicate);
112+
113+
$m->load(2)->set('float', 8.202343767574731)->save();
114+
// pack is needed to compare float numbers exactly, see https://github.com/sebastianbergmann/phpunit/issues/4966
115+
// remove bin2hex/pack once fixed in phpunit officially
116+
$this->assertSame(bin2hex(pack('e', 8.202343767574731)), bin2hex(pack('e', $m->load(2)->get('float'))));
112117
}
113118

114119
public function testEmptyValues(): void

0 commit comments

Comments
 (0)