@@ -209,27 +209,48 @@ public function convert(string $targetUnitClassOrType): UnitInterface
209209 public function normalize (): UnitInterface
210210 {
211211 $ mapping = static ::getMapping ();
212- $ sourceUnitClass = $ mapping [static ::getUnitType ()] ?? null ;
213212
214- if (null === $ sourceUnitClass ) {
215- throw new \ InvalidArgumentException ( \sprintf ( " Normalization from '%s' is not supported. " , static ::class) );
213+ if (0 === $ this -> value -> compare ( new Number ( 0 )) ) {
214+ return new static ( 0 );
216215 }
217216
218- $ shortest = $ this ;
217+ $ candidates = [] ;
219218
220- foreach ($ mapping as $ targetUnitClass ) {
221- if (static ::class === $ targetUnitClass ) {
222- continue ;
219+ foreach ($ mapping as $ unitClass ) {
220+ $ converted = $ this ->convert ($ unitClass );
221+ $ absValue = abs ((float ) $ converted ->getValue ()->value );
222+
223+ // Collect candidates where the number is at least 1.
224+ if ($ absValue >= 1 ) {
225+ $ candidates [] = [
226+ 'unit ' => $ converted ,
227+ 'value ' => $ absValue ,
228+ ];
223229 }
230+ }
231+
232+ // >= 1
233+ if (0 !== \count ($ candidates )) {
234+ usort ($ candidates , static function ($ a , $ b ) {
235+ return $ a ['value ' ] <=> $ b ['value ' ];
236+ });
237+
238+ return $ candidates [0 ]['unit ' ];
239+ }
240+
241+ // < 1
242+ $ bestCandidate = null ;
224243
225- $ converted = $ this ->convert ($ targetUnitClass );
244+ foreach ($ mapping as $ unitClass ) {
245+ $ converted = $ this ->convert ($ unitClass );
246+ $ absValue = abs ((float ) $ converted ->getValue ()->value );
226247
227- if (\strlen ( $ converted -> format ()) < \strlen ( $ shortest -> format ()) ) {
228- $ shortest = $ converted ;
248+ if (null === $ bestCandidate || $ absValue > $ bestCandidate [ ' value ' ] ) {
249+ $ bestCandidate = [ ' unit ' => $ converted, ' value ' => $ absValue ] ;
229250 }
230251 }
231252
232- return $ shortest ;
253+ return $ bestCandidate [ ' unit ' ] ?? $ this ;
233254 }
234255
235256 public static function create (Number |string |int |float $ value , string $ unitType ): static
0 commit comments