Used colon-less keyword syntax in method signatures where the optional variable name...
[cslatevm.git] / src / core / numeric.slate
blob71dd9aef705ee1de5090530aff4aae953a499051
1 prototypes ensureNamespace: #numerics &delegate: True.
3 numerics define: #Number &parents: {Comparable}.
4 "A Number is a Comparable value upon which arithmetic operations may be performed."
6 n@(Number traits) abs
7 "The absolute value."
9   n isNegative ifTrue: [n negated] ifFalse: [n]
12 n@(Number traits) negated
13 "The argument's additive inverse generically."
14 [n zero - n].
16 n@(Number traits) isZero
17 "This method tests for zero generically."
18 [n = n zero].
20 n@(Number traits) isPositive
21 "Whether it's positive generically."
22 [n > n zero].
24 n@(Number traits) isNegative
25 "Whether it's negative generically."
26 [n < n zero].
28 n@(Number traits) isUnit
29 "This method tests for one generically."
30 [n = n unit].
32 n@(Number traits) sign
33 "Answers 1 for positive, -1 for negative, 0 for zero."
35   n isZero
36     ifTrue: [0]
37     ifFalse: [n isPositive ifTrue: [1] ifFalse: [-1]]
40 _@(Number traits) isInfinite [False].
42 n@(Number traits) zero
43 "This method returns the zero element for the numeric type.
44 So, n * n zero = n zero."
45 [0].
47 n@(Number traits) unit
48 "This method returns the unit element for the numeric type.
49 So, n * n unit = n."
50 [1].
52 n@(Number traits) divideByZero
53 "The default handler for division by zero."
55   [(DivideByZero of: n) signal] handleWith: DivideByZero ReturnInput
58 numerics define: #CoercibleNumberMixin &parents: {Cloneable}.
59 "A CoercibleNumberMixin integrates a Number into the coercible tower of Numbers."
61 t@(CoercibleNumberMixin traits) level
63 overrideThis
66 numerics define: #Integer &parents: {Number. CoercibleNumberMixin}.
68 SmallInteger traitsWindow atSlotNamed: #traits1 put: Integer traits.
69 SmallInteger traitsWindow atSlotNamed: #traits2 put: Number traits.
70 SmallInteger traitsWindow atSlotNamed: #traits3 put: Comparable traits.
71 SmallInteger traitsWindow atSlotNamed: #traits4 put: CoercibleNumberMixin traits.
75 SmallInteger traitsWindow _delegates: 
76   {CoercibleNumberMixin traits. Comparable traits. Number traits. Integer traits. SmallInteger traits}.
80 SmallInteger traits minimumValue ::= lobby smallIntegerMinimum.
81 SmallInteger traits maximumValue ::= lobby smallIntegerMaximum.
82 SmallInteger traits level ::= 0.
83 "Level of the number type for coercion purposes."
85 i@(SmallInteger traits) bitAt: n
86 [(i bitAnd: 1 << n) sign].
88 i@(SmallInteger traits) highBit
89 [| n bit |
90   i = SmallInteger minimumValue
91     ifTrue: [^ (i bitNot highBit + 1)].
92   bit := 0.
93   n := i abs.
94   [n > 2r1]
95     whileTrue: [bit += 1. n := n bitShift: -1].
96   bit
99 x@(SmallInteger traits) bitShiftOverflow: y@(SmallInteger traits)
101   (x as: BigInteger) bitShift: y
104 x@(SmallInteger traits) addOverflow: y@(SmallInteger traits)
106   (x as: BigInteger) + (y as: BigInteger)
109 x@(SmallInteger traits) subtractOverflow: y@(SmallInteger traits)
111   (x as: BigInteger) - (y as: BigInteger)
114 x@(SmallInteger traits) multiplyOverflow: y@(SmallInteger traits)
116   (x as: BigInteger) * (y as: BigInteger)
119 numerics define: #Float &parents: {Number. CoercibleNumberMixin}.
121 n@(Float traits) zero
122 "This method returns the zero element for the numeric type.
123 So, n * n zero = n zero."
124 [0.0].
126 n@(Float traits) unit
127 "This method returns the unit element for the numeric type.
128 So, n * n unit = n."
129 [1.0].
131 x@(Float traits) isNaN
132 "Simple, endianness-independent test for Not-a-Number."
133 [x ~= x].
135 f@(Float traits) as: _@(Float traits)
136 [f].
138 n@(Number traits) isNaN
139 "Compatibility with Float."
140 [False].
143 SingleFloat traitsWindow atSlotNamed: #traits1 put: Float traits.
144 SingleFloat traitsWindow atSlotNamed: #traits2 put: Number traits.
145 SingleFloat traitsWindow atSlotNamed: #traits3 put: Comparable traits.
146 SingleFloat traitsWindow atSlotNamed: #traits4 put: CoercibleNumberMixin traits.
149 SingleFloat traitsWindow _delegates: 
150   {ByteArray traits. CoercibleNumberMixin traits. Comparable traits. Number traits. Float traits. SingleFloat traits}.
152 SingleFloat traits level ::= 3.
153 "Level of the number type for coercion purposes."
155 SingleFloat traits tolerance ::= 0.0001.
157 _@(Number traits) tolerance [0].
159 f@(SingleFloat traits) hash
161   f significand bitXor: f exponent
164 x@(Number traits) isCloseTo: y@(Number traits)
165 "Whether the two Floats are close to each other in value."
167   `conditions: (
168     [x isZero] -> [y abs < y tolerance].
169     [y isZero] -> [x abs < x tolerance].
170     [x isNaN \/ [y isNaN]] -> [False]
171   ) otherwise: [(x - y) abs <= (x tolerance min: y tolerance)]
174 f@(SingleFloat traits) significandSize
176   23
179 f@(SingleFloat traits) exponentSize
181   8
184 f@(SingleFloat traits) bias
186   127
189 x@(Float traits) raisedTo: y@(Float traits)
190 "Implements floating-point exponentiation in terms of the natural logarithm
191 and exponential primitives - this is generally faster than the naive method."
193   `conditions: (
194     [y isZero] -> [x unit].
195     [x isZero \/ [y isUnit]] -> [x]
196   ) otherwise: [(x ln * y) exp]
199 f@(Float traits) truncated
200 [| significand exponent n |
201   significand := f significand.
202   exponent := f exponent.
203   exponent = (f bias * 2 + 1) ifTrue:
204     [error: 'Can\'t coerce floating-point Inf or NaN to an integer.'].
205   exponent isZero ifTrue:
206     [^ (significand isZero
207           ifTrue: [0]
208           ifFalse: [f isNegative
209                       ifTrue: [-1]
210                       ifFalse: [0]])].
211   exponent -= f bias.
212   significand := (1 bitShift: f significandSize) bitOr: significand.
213   n := significand bitShift: exponent - f significandSize.
214   f isNegative
215     ifTrue: [n negated]
216     ifFalse: [n]
219 f@(Float traits) as: _@(Integer traits)
221   f truncated
224 i@(Integer traits) as: _@(Float traits)
225 [| f n length significand bits newF |
226   i isZero
227     ifTrue: [^ SingleFloat zero].
228 "  f := i highBit <= SingleFloat significandSize
229     ifTrue: [SingleFloat]
230     ifFalse: [DoubleFloat].
232   f := SingleFloat.
233   n := i abs.
234   length := n highBit.
235   length > f bias
236     ifTrue:
237       [error: 'Integer is too large to coerce to floating-point value.'].
238   significand :=
239    ((n bitShift: f significandSize - length)
240      bitAnd: (1 bitShift: f significandSize) - 1).
241   newF := f withSignificand: significand exponent: length + f bias.
242   i isNegative
243    ifTrue: [newF negated]
244    ifFalse: [newF]
247 "Constants"
248 numerics Pi ::= 3.141592654.
249 numerics E ::= 2.718281828.
251 n@(Number traits) squared
252 "The square of the number."
253 [n * n].
255 n@(Number traits) sqrt
256 "The square root of the number."
258   n isNegative ifTrue: [(n as: Complex) sqrt]
259     ifFalse: [n raisedTo: 1 / 2]
262 n@(Integer traits) succ
263 "Answer the Integer's successor."
264 [n + 1].
266 n@(Integer traits) pred
267 "Answer the Integer's predecessor."
268 [n - 1].
270 n@(Integer traits) factorial
271 "The standard recursive definition."
273   n isNegative ifTrue: [error: 'Negative inputs to factorial are invalid.'].
274   n <= 1
275     ifTrue: [1]
276     ifFalse: [n * ((n - 1) factorial)]
279 x@(Integer traits) gcd: y@(Integer traits)
280 "Euclid's algorithm for finding the greatest common divisor."
281 [| n m temp |
282   n := x.
283   m := y.
284   [n isZero] whileFalse: [temp := n. n := m \\ temp. m := temp].
285   m abs
288 x@(Number traits) quo: y@(Number traits)
289 "Division rounded towards zero."
291   (x / y) truncated
294 x@(Number traits) rem: y@(Number traits)
295 "Find the modulus (remainder) of a pair of numbers. Floats will return a non-
296 Integer difference."
298   x - ((x quo: y) * y)
301 x@(Number traits) quoRem: y@(Number traits)
302 "Calculate the quotient and the remainder, ideally at once, of x and y."
304   {x quo: y. x rem: y}
307 x@(Number traits) mod: y@(Number traits)
308 "An alias for rem:."
310   x rem: y
313 base@(Integer traits) raisedTo: expon mod: n
314 "Answer (base raisedTo: expon) mod: n, only more efficiently than that.
315 It works in the standard way, by square-and-multiply, expanding the
316 exponent into a sum of powers of 2, and factoring the base by this
317 as it proceeds."
319   expon isNegative
320     ifTrue: [(base raisedTo: (expon negated) mod: n) inverseMod: n]
321     ifFalse:
322       [| z |
323        z := 1.
324        [expon isZero] whileFalse:
325         [[(expon mod: 2) isZero] whileTrue:
326           [expon := expon // 2.
327            base := base squared mod: n].
328          expon -= 1.
329          z := z * base mod: n]
330        z]
333 m@(Integer traits) inverseMod: n@(Integer traits)
334 "Answer x such that (m * x) \\ n = 1."
335 [| a b q |
336   a := 1. b := 0.
337   [m isZero] whileFalse:
338     [q := n // m. m := n \\ (n := m). a := b - (q * (b := a))].
339   n ~= 1 ifTrue: [error: 'Integer does not have an inverse.'].
340   b
343 x@(Number traits) isEven
344 "Answer whether the Number is even; modulo tells us the remainder of division."
346   (x rem: 2) isZero
349 x@(Number traits) isOdd
350 "Odd numbers are those which are not even."
352   x isEven not
355 m@(Integer traits) isPrime
356 "Whether the Integer is evenly divisible by no other Integers than 1 and
357 itself."
358 [| k q |
359   m isEven ifTrue: [^ (m = 2)].
360   k := 1.
361   q := m - 1 bitShift: -1.
362   [q isOdd]
363     whileFalse:
364       [q := q bitShift: -1.
365        k += 1].
366   25 timesRepeat: [(m isProbablyPrimeWithK: k andQ: q) ifFalse: [^ False]].
367   True
370 m@(Integer traits) isProbablyPrimeWithK: k andQ: q
371 "Algorithm P, probabilistic primality test, from
372 Knuth, Donald E. 'The Art of Computer Programming', Vol 2,
373 Third Edition, section 4.5.4, page 395."
374 [| x j y |
375   x := (m - 2) atRandom + 1.
376   j := 0.
377   y := x raisedTo: q mod: m.
378   [(j isZero /\ [y isUnit] \/ [y + 1 = m]) ifTrue: [^ True].
379    j isPositive /\ [y isUnit] ifTrue: [^ False].
380    True]
381     whileTrue:
382       [(j += 1) < k
383          ifTrue: [y := y squared \\ m]
384          ifFalse: [^ False]]
387 n@(Integer traits) primesDo: block
388 "Decomposes the Integer into primes, applying the block to each (in increasing
389 order)."
390 [| div next remaining |
391   div := 2.
392   next := 3.
393   remaining := n.
394   [[(remaining \\ div) isZero]
395      whileTrue:
396        [block apply*, div.
397         remaining := remaining // div].
398    remaining = 1] whileFalse:
399      [div := next.
400       next += 2] "Just looks at the next odd integer."
403 x@(Number traits) truncated
404 "The greatest lesser Integer value."
405 [x quo: 1].
407 x@(Integer traits) truncated
408 "Integers have no fractional part."
409 [x].
411 i@(Integer traits) as: _@(Integer traits)
412 "By default integers merely coerce to themselves."
413 [i].
415 x@(Number traits) ln
416 "Define the natural logarithm in terms of the Float primitive."
417 [(x as: Float) ln].
419 x@(Number traits) log: base
420 "Define the logarithm-base-N in terms of natural logarithm ratios."
421 [x ln / base ln].
423 x@(Number traits) log10
424 [x log: 10].
426 x@(Number traits) exp
427 "Define E raisedTo: x in terms of the Float primitive."
428 [(x as: Float) exp].
430 x@(Number traits) ceiling
431 "The smallest greater Integer value."
433   trunc ::= x truncated.
434   x = trunc \/ [x isNegative]
435     ifTrue: [trunc]
436     ifFalse: [trunc + 1]
439 x@(Number traits) floor
440 "The largest lesser Integer value."
442   trunc ::= x truncated.
443   x = trunc \/ [x isPositive]
444     ifTrue: [trunc]
445     ifFalse: [trunc - 1]
448 x@(Integer traits) ceiling
449 "Integers have no fractional part."
450 [x].
452 x@(Integer traits) floor
453 "Integers have no fractional part."
454 [x].
456 i@(Integer traits) highBit
457 [(i ln / 2 ln) ceiling].
459 i@(Integer traits) lowBit
461   i = SmallInteger minimumValue
462     ifTrue: [i highBit]
463     ifFalse: [(i bitXor: i - 1) highBit]
466 x@(Integer traits) << y@(Integer traits)
467 "Left-bit-shift by the given amount."
469   x bitShift: y
472 x@(Integer traits) >> y@(Integer traits)
473 "Right-bit-shift by the given amount."
475   x bitShift: y negated
478 x@(Integer traits) rounded
479 "Integers round to themselves."
480 [x].
482 x@(Float traits) rounded
483 "Answer the integer nearest to x."
484 [(x + 0.5) floor].
486 x@(Number traits) roundTo: q@(Number traits)
487 "Answer the nearest number which is a multiple of q."
488 [(x / q) rounded * q].
490 x@(Number traits) fractionPart
491 "Return the difference between the integral part of the number and itself."
493   x - x truncated
496 x@(Number traits) \\ y@(Number traits)
497 "Answer the remainder of dividing x by y."
499   x - (x // y * y)
502 x@(Number traits) reciprocal
503 "Answer the multiplicative inverse."
505   x isZero
506     ifTrue: [x divideByZero]
507     ifFalse: [x unit / x]
510 x@(CoercibleNumberMixin traits) coerceTo: y@(CoercibleNumberMixin traits)
511 "Convert x to the same type as y, only in order of ascending level."
513   x level < y level ifTrue: [x as: y] ifFalse: [x]
516 "Generic arithmetic methods. These work by catching any arithmetic
517 operation with dissimilar types and converting the less generic type to
518 the more generic type. They then dispatch the converted arguments to the
519 method which handles that operation for matched types.
520 E.g. Float + Complex and Complex + Float will both dispatch to
521 Complex + Complex"
522 x@(CoercibleNumberMixin traits) + y@(CoercibleNumberMixin traits) [(x coerceTo: y) + (y coerceTo: x)].
523 x@(CoercibleNumberMixin traits) - y@(CoercibleNumberMixin traits) [(x coerceTo: y) - (y coerceTo: x)].
524 x@(CoercibleNumberMixin traits) * y@(CoercibleNumberMixin traits) [(x coerceTo: y) * (y coerceTo: x)].
525 x@(CoercibleNumberMixin traits) / y@(CoercibleNumberMixin traits) [(x coerceTo: y) / (y coerceTo: x)].
526 x@(CoercibleNumberMixin traits) < y@(CoercibleNumberMixin traits) [(x coerceTo: y) < (y coerceTo: x)].
527 x@(CoercibleNumberMixin traits) = y@(CoercibleNumberMixin traits) [(x coerceTo: y) = (y coerceTo: x)].
529 x@(CoercibleNumberMixin traits) raisedTo: y@(CoercibleNumberMixin traits) [(x coerceTo: y) raisedTo: (y coerceTo: x)].
531 x@(CoercibleNumberMixin traits) bitAnd: y@(CoercibleNumberMixin traits) [(x coerceTo: y) bitAnd: (y coerceTo: x)].
532 x@(CoercibleNumberMixin traits) bitOr: y@(CoercibleNumberMixin traits) [(x coerceTo: y) bitOr: (y coerceTo: x)].
533 x@(CoercibleNumberMixin traits) bitXor: y@(CoercibleNumberMixin traits) [(x coerceTo: y) bitXor: (y coerceTo: x)].
535 x@(Integer traits) bitNot
537   x negated - 1
540 x@(Integer traits) bitShift: y@(Integer traits)
542   (x * (2 raisedTo: y)) truncated
545 x@(Integer traits) // y@(Integer traits)
546 "Integer division."
548   y isZero
549     ifTrue: [x divideByZero]
550     ifFalse:
551       [q ::= x quo: y.
552        (x isNegative xor: y isNegative) /\ [q * y ~= x]
553          ifTrue: [q - 1]
554          ifFalse: [q]]
557 x@(Integer traits) / y@(Integer traits)
558 "This is a provisional stub in case Fraction does not override it."
560   y isZero
561     ifTrue: [x divideByZero]
562     ifFalse:
563       [(x rem: y) isZero
564          ifTrue: [x quo: y]
565          ifFalse: [(Fraction newFor: x over: y) reduced]]
568 x@(Integer traits) lcm: y@(Integer traits)
569 "Find the least common multiple of the pair."
571   x // (x gcd: y) * y
574 n@(Integer traits) taken: r@(Integer traits)
575 "Calculates the number of combinations of N elements taken R at a time.
576 It's zero outside of Pascal's triangle."
577 [| num denom |
578   r isNegative \/ [r > n] ifTrue: [^ 0].
579   num := 1.
580   n above: (r max: n - r)
581     do: [| :factor | num *= factor].
582   denom := 1.
583   1 to: (r min: n - r)
584     do: [| :factor | denom *= factor].
585   num // denom
588 n@(Integer traits) hashMultiply
589 "A copying of Squeak's hash-multiplier. TODO: To Be Replaced."
591   low28 ::= n bitAnd: 268435455.
592   low14 ::= low28 bitAnd: 16383.
593   9741 * low14 + ((9741 * (low28 bitShift: -14) + (101 * low14)
594                      bitAnd: 16383) * 16384) bitAnd: 268435455
597 x@(Number traits) raisedTo: y@(Integer traits)
599   `conditions: (
600     [y isZero] -> [x unit].
601     [x isZero \/ [y = 1]] -> [x].
602     [y isPositive]
603       -> "(x * x raisedTo: y // 2) * (x raisedTo: y \\ 2)"
604       [| count result |
605        count := 1.
606        [(count := count bitShift: 1) < y] whileTrue.
607        result := x unit.
608        [count isPositive]
609          whileTrue:
610            [result := result squared.
611             (y bitAnd: count) isZero ifFalse: [result *= x].
612             count := count bitShift: -1].
613        result]
614   ) otherwise: [(x raisedTo: y negated) reciprocal]
617 numerics define: #UniqueNumber &parents: {Number}.
619 numerics LargeUnbounded ::= UniqueNumber clone.
620 "A quantity which is unbounded but still a Number: as-large-as-you-like. It's
621 definitely not an infinity."
623 x@(Comparable traits) < _@LargeUnbounded
624 [True].
626 _@LargeUnbounded < _@LargeUnbounded
627 [False].
629 numerics define: #Infinity &parents: {UniqueNumber}.
631 _@(Infinity traits) isInfinite [True].
633 inf@(Infinity traits) * x
635   x isZero
636     ifTrue: [x]
637     ifFalse:
638       [x isNegative
639          ifTrue: [inf negated]
640          ifFalse: [inf]]
643 inf@(Infinity traits) + _@(Number traits)
644 [inf].
646 _@(Number traits) + inf@(Infinity traits)
647 [inf].
649 inf@(Infinity traits) - _@(Number traits)
650 [inf].
652 _@(Number traits) - inf@(Infinity traits)
653 [inf negated].
655 numerics PositiveInfinity ::= Infinity clone.
657 _@PositiveInfinity isInfinite [True].
659 x@(Comparable traits) < pi@PositiveInfinity
661   pi ~= x
664 pi@PositiveInfinity < x@(Comparable traits)
665 [False].
667 _@PositiveInfinity printOn: s
669   s ; 'positive infinity'
672 numerics NegativeInfinity ::= Infinity clone.
674 ni@NegativeInfinity < x@(Comparable traits)
676   ni ~= x
679 x@(Comparable traits) < pi@NegativeInfinity
680 [False].
682 _@NegativeInfinity printOn: s
684   s ; 'negative infinity'
687 _@PositiveInfinity negated
688 [NegativeInfinity].
690 _@NegativeInfinity negated
691 [PositiveInfinity].
693 numerics define: #Epsilon &parents: {UniqueNumber}.
695 x@(Epsilon traits) = y
696 [x == y].
698 _@(Epsilon traits) isZero
699 [False].
701 x@(Number traits) * y@(Epsilon traits)
703   x isZero
704     ifTrue: [x]
705     ifFalse:
706       [x isNegative
707         ifTrue: [y negated]
708         ifFalse: [y]]
711 x@(Epsilon traits) / y@(Number traits)
713   y isZero
714     ifTrue: [x divideByZero]
715     ifFalse:
716       [y isNegative
717         ifTrue: [x negated]
718         ifFalse: [x]]
721 x@(Number traits) / y@(Epsilon traits)
723   x isNegative
724     ifTrue: [y recriprocal negated]
725     ifFalse: [y recriprocal]
728 x@(Epsilon traits) * y@(Number traits)
729 [y * x].
731 x@(Number traits) + _@(Epsilon traits)
732 [x].
734 _@(Epsilon traits) + x@(Number traits)
735 [x].
737 x@(Number traits) - _@(Epsilon traits)
738 [x].
740 _@(Epsilon traits) - x@(Number traits) 
741 [x negated].
743 numerics PositiveEpsilon ::= Epsilon clone.
744 "The reciprocal of PositiveInfinity."
746 _@PositiveEpsilon isPositive
747 [True].
749 _@PositiveInfinity reciprocal
750 [PositiveEpsilon].
752 _@PositiveEpsilon reciprocal
753 [PositiveInfinity].
755 _@PositiveEpsilon as: x@(Number traits)
756 [0.0 as: x].
758 x@(Number traits) < _@PositiveEpsilon
760   x isPositive not
763 _@PositiveEpsilon < x@(Number traits)
765   x isPositive
768 numerics NegativeEpsilon ::= Epsilon clone.
769 "The reciprocal of NegativeInfinity."
771 x@(Number traits) < _@NegativeEpsilon
773   x isNegative
776 _@NegativeEpsilon < x@(Number traits)
778   x isNegative not 
781 _@NegativeEpsilon isNegative
782 [True].
784 _@NegativeInfinity reciprocal
785 [NegativeEpsilon].
787 _@NegativeEpsilon reciprocal
788 [NegativeInfinity].
790 _@NegativeEpsilon as: x@(Number traits)
792   -0.0 as: x
795 _@PositiveEpsilon negated
796 [NegativeEpsilon].
798 _@NegativeEpsilon negated
799 [PositiveEpsilon].
801 "Yuck! This should be in dimensioned.slate but is here for now"
802 "TODO: Move this"
803 n@(Number traits) degreesToRadians
804 [n * Pi / 180].
806 n@(Number traits) radiansToDegrees
807 [n * 180 / Pi].
809 n@(Number traits) readFrom: s
810 "Reads the first thing in the String (or Stream) as a Number.
811 An error is raised if the return type does not match the requested one.
812 Use as: if there is already a String whose full contents are exactly the
813 digits."
815   ((next ::= (Syntax Lexer newOn: s reader) readNumber value) is: n)
816     ifFalse: [error: 'The source did not parse into ' ; n printName asAn ; '.'].
817   next
820 n@(Integer traits) readFrom: s &radix
822   radix `defaultsTo: 10.
823   ((next ::= (Syntax Lexer newOn: s reader) readInteger: radix) is: n)
824     ifFalse: [error: 'The source did not parse into ' ; n printName asAn ; '.'].
825   next
828 "A portable way to represent floating point numbers without loss of precision
829 http://research.microsoft.com/~hollasch/cgindex/coding/portfloat.html
830 Would be useful in #storeOn: #loadFrom: for floats"
832 n@(Float traits) storeOn: s
833 "Stores a float in portable encoding"
836 n@(Float traits) loadFrom: s
837 "Loads a float in portable encoding"