Number API Functions: Unterschied zwischen den Versionen

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen
 
(250 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
This document lists most useful (and most often needed) functions.
This document lists most useful (and most often needed) functions.
Be aware, that there are many more to be found in either the class references or via the builtin class browser.
Be aware, that there are many more to be found in either the class references or via the builtin [[Tools_ClassBrowser/en | class browser]].


See also [[Expecco_API/en#Numbers | "Numbers"]] in [[Expecco_API]].
<br>
Reference: [http://live.exept.de/ClassDoc/classDocOf:,Integer Integer], [http://live.exept.de/ClassDoc/classDocOf:,Float Float], [http://live.exept.de/ClassDoc/classDocOf:,Fraction Fraction], [http://live.exept.de/ClassDoc/classDocOf:,FixedPoint ScaledDecimal], [http://live.exept.de/ClassDoc/classDocOf:,Complex Complex]
Reference: [http://live.exept.de/ClassDoc/classDocOf:,Integer Integer], [http://live.exept.de/ClassDoc/classDocOf:,Float Float], [http://live.exept.de/ClassDoc/classDocOf:,Fraction Fraction], [http://live.exept.de/ClassDoc/classDocOf:,FixedPoint ScaledDecimal], [http://live.exept.de/ClassDoc/classDocOf:,Complex Complex]
which all inherit from
which all inherit from
Zeile 13: Zeile 15:


===== Integer Literals =====
===== Integer Literals =====
<code>1234
1234
1234567890123456789012345678901234567890
<br>16rFFAA</code> or <code>0xaffe
-123456789012345678901234567890
<br>2r0101</code> or <code>0b101010
0xaffe or 16rFFAA <small>(hex in C/JSON or Smalltalk syntax)</small>
<br>8r377</code> or <code>0o377
-0xaffe or 16r-FFAA <small>(negative hex in C- or Smalltalk syntax)</small>
<br>&lt;''N''&gt;rXXX
0b101010 or 2r0101 <small>(binary in C/JSON or Smalltalk syntax)</small>
<br>1234567890123456789012345678901234567890
0o377 or 8r377 <small>(octal)</small>
<br>-123456789012345678901234567890</code>
&lt;''N''&gt;rXXX <small>(arbitrary radix N)</small>
::integer constant; decimal, hex, binary, octal or any base ''N'';<br>integers may be arbitrary long
Integer constant; decimal, hex, binary, octal or any base ''N'';<br>integers may be arbitrary long


===== Floating Point Literals (Limited Precision Rationals) =====
===== Floating Point Literals (Limited Precision Rationals) =====
<code>0.5
0.5
<br>1e5
1e5
<br>-1.2e-3
-1.2e-3
12.6789q or 1.7e-21q <small>(extended precision)</small>
<br>1345.6789q5</code>
3.6789f or 2.67e5f <small>(single precision)</small>
::float constant; actually double precision;<br>use "q" instead of "e" for extra precision (extended IEEE floats)
Float constant; actually IEEE double precision;<br>use "q" instead of "e" for extra precision (extended IEEE floats) or "f" for single/less precision.

In addition to single, double and extended floats, additional precision representations are available (see below).


===== Fraction Literals =====
===== Fraction Literals =====
<code>(4/3)
(4/3)
<br>(523423432/3)</code>
(523423432/3)
(-5/3)
:: fraction constants (numerator / denominator); these are exact
Fraction constants (numerator / denominator); these are exact


===== Scaled Decimal Literals =====
===== Scaled Decimal Literals =====
<code>123.456s2
123.456s2
-33.4s2
<br>100s2</code>
100s2
::scaled decimal; prints itself rounded to 2 fractional digits eg. "123.46" or "100.00" (although internally, the full precision is kept for further operations)
Scaled decimal; the number after the "s" defines the print-scale. The above numbers print themself rounded to 2 fractional digits e.g. "123.46", "-33.40" or "100.00" (although internally, the full precision is kept for further operations).


===== Complex Number Literals =====
===== Complex Number Literals =====
(4+3i) or (-5+2i) or (-10-4i)
<code>(4+3i)
<br>(4.3+3.1i)
(4.3+3.1i) or (4.3 + 1i)
<br>5.0 i</code>
5.0 i or 5i
:: a complex number (real part / imaginary part)
Complex number (real part / imaginary part)


== Wellknown Constant Numbers ==
== Wellknown Constant Numbers ==
A few constants are known by name.
A few common constants are known by name.
They are answered by corresponding getter messages sent to the number class (of which you want the constant):
They are answered by corresponding getter messages sent to the number class of which you want the constant (i.e. these return the constants in their respective precision):


<code>Float pi</code>
:Float '''pi'''
::pi as IEEE double precision number
::pi as IEEE double precision number
<code>LongFloat pi</code>
::pi as IEEE extended precision number


:FloatD '''pi'''
<code>Float ln2</code>
:Float64 '''pi'''
<br><code>Float ln10</code>
::the same as above (FloatD and Float64 are aliases for the default float class "Float")
<br><code>Float phi</code>
:FloatQ '''pi'''
<br><code>Float sqrt2</code>
:Float80 '''pi'''
<br><code>Float e</code>
::pi as IEEE extended precision number (FloatQ and Float80 are aliases for the extended float class also known as "LongFloat")
:FloatE '''pi'''
:Float32 '''pi'''
::pi as IEEE extended precision number (FloatE and Float32 are aliases for the single precision float class also known as "ShortFloat")

:<FloatClass> '''ln2'''
:<FloatClass> '''ln10'''
:
:<FloatClass> '''sqrt2'''
:<FloatClass> '''sqrt3'''
:<FloatClass> '''e'''
:
:<FloatClass> '''NaN''', '''infinity''' and '''negativeInfinity'''

Take a look at the class in a class browser for additional useful constants.


== Float Representations ==
== Float Representations ==
=== Standard Float Representations ===
=== Standard Float Representations ===
For traditional reasons, the name "''Float''" refers to IEEE double precision floating point numbers in expecco, whereas IEEE single precision floats are called "''ShortFloats''".
For traditional reasons, the name "''Float''" refers to IEEE double precision floating point numbers in expecco, whereas IEEE single precision floats are called "''ShortFloats''".
For more readability, the float classes can also be referred to via their aliases:
:Float32 = FloatE (=ShortFloat),
:Float64 = FloatD (=Float)
:Float80 = FloatQ (=LongFloat).


There is usually no need to explicitly use or refer to ShortFloats: modern CPUs usually process them as fast as doubles. However, you may need them to either simulate single precision arithmetic (which may show different convergence behavior in some series computations) or to exchange binary data with other systems (i.e. to generate a byteArray containing the float's bits).
There is usually no need to explicitly use or refer to ShortFloats (or FloatEs): modern CPUs usually process them as fast as doubles.<br>However, you may need them to either simulate single precision arithmetic (which may show different convergence behavior in some series computations) or to exchange binary data with other systems (i.e. to generate a byteArray containing the float's bits or to write a single precision float's bits to a stream).


====== Float ======
====== Float / FloatD / Float64 ======
Floats (double precision IEEE floats) are stored in 64 bits, having an 11-bit exponent and a 52+1 bit mantissa (1 bit is hidden due to normalization).<br>This gives roughly 15 digits of precision.
Floats (double precision IEEE floats) are stored in 64 bits, having an 11-bit exponent and a 52+1 bit mantissa (1 bit is hidden due to normalization).<br>This gives roughly 15 digits of precision.<br>This is the default used, if you write a float number in the code.


====== ShortFloat ======
====== ShortFloat / FloatE / Float32 ======
ShortFloats (single precision IEEE floats) are stored in 32 bits, having an 8-bit exponent and a 23+1 bit mantissa (1 bit is hidden due to normalization).<br>This gives roughly 7 digits of precision.
ShortFloats (single precision IEEE floats) are stored in 32 bits, having an 8-bit exponent and a 23+1 bit mantissa (1 bit is hidden due to normalization).<br>This gives roughly 7 digits of precision.


====== LongFloat ======
====== LongFloat / FloatQ / Float80 ======
LongFloats (extended precision IEEE floats) are stored in 80 bits, having an 15-bit exponent and a 64 bit mantissa.<br>This gives roughly 19 digits of precision.
LongFloats (extended precision IEEE floats) are stored in 80 bits, having a 15-bit exponent and a 64 bit mantissa.<br>This gives roughly 19 digits of precision.



Floats print themself with either a decimal point or an exponent indicator 'e', eg. "0.5", "10.0" or "1.3e3"
By Default, Floats print themself with either a decimal point or an exponent indicator 'e', e.g. "0.5", "10.0" or "1.3e3". However, there are a number of functions provided to print numbers in other formats.


=== Experimental Extra Float Representations ===
=== Experimental Extra Float Representations ===
For background information on why you should not trust IEEE floating point arithmetic, and why you may need more precision in some situations,
Expecco includes experimental versions for higher precision floats. Please do not use them for production code. They are considered being "''work in progress''", and may or may not work as expected. Especially trigonometric and other math functions are known to be erroneous.
please read the article "[[Do not trust Floating Point]]".


Expecco includes experimental versions for higher precision floats. Please do not use them for production code. They are considered being "''work in progress''", and may or may not work as expected. Especially trigonometric and other math functions are known to be erroneous or generate less precise results as expected. Please use those with extra care and report bugs.
====== QDouble ======

QDoubles use 4 double precision floats (holding the unevaluated sum of 4 doubles) to represent a float with roughly 200 bits of precision (actually often more, depending on the values).<br>QDoubles are able to represent sums/differences of a very large float with a very small float.<br>For example <code>(1e200 + 1e-15) - 1e200 -> 0.0</code>(floats loose the small value), whereas in <code>(1e200 asQDouble + 1e-15) - 1e200 -> 1e-15</code> it is preserved.
For now, we recommend the use of LargeFloat instead of QuadFloat/OctaFloat or QDouble if large precision is needed.
:

:QDoubles are thus able to represent sums of wildly distant numbers.
====== LargeFloat ======
:With regular floats, the following computations all deliver a wrong result:
LargeFloats use an arbitrary (configurable) number of bits to represent floats with any precision.<br>They are completely software emulated, which makes most operations much slower than with other floats. In other languages, these are sometimes called "''BigFloat''".
1e200 + 1e-15 + 1e-100 -> 1E+200 (loosing 1e-15 + 1e-100)

(1e200 + 1e-15 + 1e-100) - 1e200 -> 0 (wrong; lost 1e-15 + 1e-100)
Usage is similar to QDoubles as described below. However, when creating aLargeFloat, you have to give the desired precision (in bits) as argument:
(1e200 + 1e-15 + 1e-100) - 1e200 - 1e-15 -> -1e-15 (wrong)
1.0 asLargeFloatPrecision:200
(1e200 + 1e-15 + 1e-100) - 1e200 - 1e-100 -> -1E-100 (wrong)
or in decimals:
(1e200 + 1e-15 + 1e-100) - 1e200 - 1e-15 - 1e-100 -> -1E-015 (wrong)
1.0 asLargeFloatDecimalPrecision:100
If no precision is given, a default prcision of 200 bits is used, as e.g. by:
1.0 asLargeFloat

You will get roughly 1 decimal digit of precision per 3 bits (i.e. the above 200bit precision corresponds to a decimal precision of roughly 60 digits).

Example <sup>(1)</sup>:
45 degrees sin
=> 0.707106781186547
(a float with roughly 15 digits precision)
(45 asLargeFloatPrecision:200) degrees sin
=> 0.70710678118654752440084436210484903928483593768847403658834
and back:
(45 asLargeFloatPrecision:200) degrees sin arcSin radiansToDegrees
=> 45.0
<sup>1)</sup> the meaning of "degrees" is described in the [[PhysicalValues/en#Angle|"Physical Values"]] document.

====== QDouble / FloatQD ======
QDoubles use 4 double precision floats (holding the unevaluated sum of 4 doubles) to represent a float with roughly 200 bits of precision (actually often more, depending on the values).<br>QDoubles are able to represent sums/differences of a very large float with a very small float.<br>For example with regular floats (i.e. IEEE double precision):
(1e200 + 1e-15) - 1e200
=> 0.0
the small value is lost.<br>Whereas with QDoubles as in:
(1e200 asQDouble + 1e-15) - 1e200
=> 1e-15
it is preserved.

QDoubles are thus able to represent sums of wildly distant numbers.
With regular floats, the following computations all deliver a wrong result:
1e200 + 1e-15 + 1e-100
=> 1E+200 (loosing 1e-15 + 1e-100)
(1e200 + 1e-15 + 1e-100) - 1e200
=> 0 (wrong; lost 1e-15 + 1e-100)
(1e200 + 1e-15 + 1e-100) - 1e200 - 1e-15
=> -1e-15 (wrong)
(1e200 + 1e-15 + 1e-100) - 1e200 - 1e-100
=> -1E-100 (wrong)
(1e200 + 1e-15 + 1e-100) - 1e200 - 1e-15 - 1e-100
=> -1E-015 (wrong)
whereas with QDoubles, we get:
whereas with QDoubles, we get:
1e200 asQDouble + 1e-15 + 1e-100 -> 1E+200 (printed, actual value is correct)
1e200 asQDouble + 1e-15 + 1e-100
=> 1E+200 (printed, actual value is correct)
(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 -> 1.0e-15 (correct)
(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-15 -> 1E-100 (correct)
(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-100 -> 1E-015 (correct)
(1e200 asQDouble + 1e-15 + 1e-100) - 1e200
(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-15 - 1e-100 -> 0.0 (correct)
=> 1.0e-15 (correct)
(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-15
=> 1E-100 (correct)
(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-100
=> 1E-015 (correct)
(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-15 - 1e-100
=> 0.0 (correct)
or another example:
or another example:
t := 1234 + 0.567890 + 0.00000012345 + 0.000000000006789.
t := 1234 + 0.567890 + 0.00000012345 + 0.000000000006789.
Zeile 109: Zeile 189:
d := c - 0.000000000006789. "/ 0.0 (correct)
d := c - 0.000000000006789. "/ 0.0 (correct)


However, there is no insurance, that bits are not lost. If one of the operands already needs all four doubles (because it cannot be represented exactly as a sum of 3 floats), bits from the second operand may be lost. For example:
:Due to the extra processing overhead, operations are slower than with doubles or extended doubles.
1e100 asQDouble + 1
will result in 1e100 (without the one), because 1e100 already uses all bits (i.e. all 4 doubles) of the QDouble.
If you need the full precision, you may have to use LargeFloats, although the processing overhead may be larger then.


Due to the extra processing overhead, operations are slower than with doubles or extended doubles.
====== QuadFloat ======

:Attention:<br>Strange results seem to be generated when regular floats are converted to QDoubles iff the original float was not representable as an exact number. For example, adding the float 0.2 to the QDouble 1.0QD will result in a number different from 1.2QD, because the original 0.2 had an error in its last bit, which gets now visible when converted to QDouble.
Better use LargeFloat instead, if more precision is needed.

====== QuadFloat / Float128 ======
QuadFloats use the 128 bit IEEE quadruple precision binary128 format, with 15 exponent bits, providing roughly 34 digits of precision.
QuadFloats use the 128 bit IEEE quadruple precision binary128 format, with 15 exponent bits, providing roughly 34 digits of precision.
<br>QuadFloats are software emulated, and thus slower than both regular floats and also slower than QDoubles.
<br>QuadFloats are software emulated, and thus computations are slower than with regular floats.

:Attention:<br>Do not use Quadfloats for now, except to convert from/from binary data. Currently, they may not handle subnormals in some arithmetic operations correctly and may also return slightly incorrect results for trigonometric operations (rounding modes are not correctly implemented). Use <!-- QDouble or --> LargeFloat if more precision is needed.
====== OctaFloat ======

====== OctaFloat / Float256 ======
OctaFloats use the 256 bit IEEE octuple binary256 format, with 19 exponent bits, providing roughly 70 digits of precision.
OctaFloats use the 256 bit IEEE octuple binary256 format, with 19 exponent bits, providing roughly 70 digits of precision.
<br>OctaFloats are also software emulated, and slower than QuadFloats.
<br>OctaFloats are also software emulated by a flexible arbitrary precision IEEE algorithm, and slower than QuadFloats and QDoubles (actually often even slower than LargeFloats below).


:Attention:<br>Do not use Octafloats for now, except to convert from/from binary data. Currently, they do not handle subnormals in some arithmetic operations correctly and may also return slightly incorrect results for trigonometric operations (rounding modes are not correctly implemented). Use <!-- QDouble or --> LargeFloat if more precision is needed.
====== LargeFloat ======
LargeFloats use an arbitrary (configurable) number of bits to represent floats with any precision.<br>They are completely software emulated which makes operations much slower than with other floats.


== Fractions ==
== Fractions ==
Zeile 132: Zeile 221:


Fractions print themself as "(''a'' / ''b'')".
Fractions print themself as "(''a'' / ''b'')".
They are computed in software and thus usually slower than float operations (especially with huge numerators/denominators).
<br>They are computed in software and thus usually slower than float operations (especially with huge numerators/denominators).


== Scaled Decimals ==
== Scaled Decimals ==
Zeile 143: Zeile 232:
a print.
a print.
=> '1234.57'
=> '1234.57'
b := 23.007 asScaledDecimal:2
b := 23.007 asScaledDecimal:2
b print.
b print.
=> '23.01'
=> '23.01'
(a + b) print.
(a + b) print.
=> '1257.57'
=> '1257.57'


This is because the sum (a+b) is actually (1234.567 + 23.007 = 1257.574), which is printed as '1257.57' (rounded).
This is because the sum (a+b) is actually (1234.567 + 23.007 = 1257.574), which is printed as '1257.57' (rounded).
<br>This also works for Fractions:
<br>Fraction example:
c := (1/3) asScaledDecimal:2.
c print.
=> '0.33'
d := (2/3) asScaledDecimal:2
d print.
=> '0.67'
(c + d) print.
=> '1.00'


However, this will look strange (i.e. wrong) if monetary values are presented this way, eg. on an invoice's summation. Here, we expect a sum of amounts to be the sum of previously listed values (think of sales tax being computed, giving a rounded Cent-value).
Be aware that the output will look strange (i.e. look wrong) if monetary values are presented this way, e.g. on an invoice's summation. Here, we'd expect a sum of amounts to be the sum of previously listed values (think of sales tax being computed, giving a rounded Cent-value).
See FixedDecimal below for a better solution.
<br>See FixedDecimal below for a better solution.


ScaledDecimals can be rounded to their scale, so that further computation are taking that value.
ScaledDecimals can be rounded to their scale, so that further computation are taking that value.
Zeile 166: Zeile 270:
== Fixed Decimals ==
== Fixed Decimals ==
(new with expecco 21.2)<br>Similar to ScaledDecimals; however, these do '''NOT''' hold the correct result, but instead '''always round''' to the specified scale and thus the value used for further operations is the (rounded) value printed.<br>
(new with expecco 21.2)<br>Similar to ScaledDecimals; however, these do '''NOT''' hold the correct result, but instead '''always round''' to the specified scale and thus the value used for further operations is the (rounded) value printed.<br>
Arithmetic operations will deliver a rounded result. Fixed decimals are good to represent money, especially when computing and printing sums of monetary values eg. in an invoice.
Arithmetic operations will deliver a rounded result. Fixed decimals are good to represent money, especially when computing and printing sums of monetary values e.g. in an invoice.
<br>Example:
<br>Example:
a := 1234.567 asFixedDecimal:2.
a := 1234.567 asFixedDecimal:2.
a print.
a print.
=> '1234.57'
=> '1234.57'
b := 23.007 asFixedDecimal:2
b := 23.007 asFixedDecimal:2
b print.
b print.
=> '23.01'
=> '23.01'
(a + b) print.
(a + b) print.
=> '1257.58'
=> '1257.58'
This looks correct eg. in an invoice's sum.
This looks correct to a human, as the values sum up correctly.


Be aware that converting a float to a FixedDecimal and back will not necessarily return the starting number, unlike ScaledDecimals. FixedDecimals do NOT preserve the original value.
Be aware that converting a float to a FixedDecimal and back will not necessarily return the starting number. Unlike ScaledDecimals, FixedDecimals do NOT preserve the original value.


If you have a pre 21.2 version, the FixedDecimal behavior can be "simulated" by forcing the decimal to round the internal value to the shown scale (as described above).
If you have a pre 21.2 version, the FixedDecimal behavior can be "simulated" by forcing a ScaledDecimal to round its value to the shown scale (as described above).

== Number Ranges ==
These behave like collections (see there) and are typically created by one of the following:
(''start'' '''to:''' ''stop'')
(''start'' '''to:''' ''stop'' '''by:''' ''step'')
For example:
(1 to:10) do:[:i |
Transcript showCR: e'{i} squared is {i squared}'.
]


== Complex Numbers ==
== Complex Numbers ==
Are created as constants "(''a'' + ''b'' i)" or created with "Complex real:''a'' imaginary:''b''".
Are created as constants "(''a'' + ''b'' i)" or created with "Complex real:''a'' imaginary:''b''".
<br>An imaginary is created with the "i" message (eg. "5 i" yields (0 + 5 i).
<br>An imaginary is created with the "i" message (e.g. "5 i" yields (0 + 5 i).
<br>Complex numbers print themself as "(''a'' + ''b'' i)".
<br>Complex numbers print themself as "(''a'' + ''b'' i)".


Complex results can also be returned from eg. square root (sort) and logarithm (log, ln) operations IFF imaginary results are trapped. I.e.
Complex results can also be returned from e.g. the square root operator (sqrt) and logarithm operations (log, ln) IFF imaginary results are trapped (which means that an exception handler for the ImaginaryResult notification is present and proceeds the exception).<br>The convenient helper "<CODE>trapImaginary:</CODE>" does that for you:
-4 sqrt
-4 sqrt
will report an error, whereas:
will report an error, whereas:
Number trapImaginary:[ -4 sqrt ]
Number trapImaginary:[ -4 sqrt ]
will return a complex result.
will return a complex result.

If imaginary results are not trapped, square root and log operators will signal an exception instead.


== Measurement Values ==
== Measurement Values ==
These hold an error percentage in addition to the actual value. These are useful to track upper and lower bounds of a measured or estimated value. Arithmetic operations will keep this error in the result.
These hold an error percentage in addition to the actual value. These are useful to track upper and lower bounds of a measured or estimated value. Arithmetic operations will keep this error in the result.
<br>They can be constructed from any number via the "±" or "±%" binary operators:
<br>They can be constructed from any number via the "</CODE>±</CODE>" or "<CODE>±%</CODE>" binary operators:


<code>(</code>''aNumber''<code>±</code> ''errRange''<code>)</code>
:'''('''''aNumber'' '''±''' ''errRange''''')'''
: a measurement value with ± an absolute error of ''errRange''.
:: a measurement value with ± an absolute error of ''errRange''.


<code>(</code>''aNumber''<code>±%</code> ''percentage''<code>)</code>
:'''('''''aNumber'' '''±%''' ''percentage''''')'''
: a measurement value with a relative error of ''percentage''.
:: a measurement value with a relative error of ''percentage''.


For example,
For example, "(50 ± 3)" represents a measurement value with 6% accuracy (i.e. the actual value is somewhere in the interval [50-3 .. 50+3]);
and "(100 ±% 3)" represents a measurement value with 3% accuracy (i.e. the value is in [100-3 .. 100+3]).
<br>"<CODE>(50 ± 3)</CODE>" represents a measurement value with 6% accuracy (i.e. the actual value is somewhere in the interval [50-3 .. 50+3]),
and
<br>"<CODE>(100 ±% 3)</CODE>" represents a measurement value with 3% accuracy (i.e. the value is in [100-3 .. 100+3]).
Measurement values are not real numbers, but can in most parts treated like one (i.e. the usual arithmetic operations are supported).
Measurement values are not real numbers, but can in most operations be treated like one (i.e. the usual arithmetic operations are supported).


== Physical Values ==
== Physical Values ==
These hold a number or measurement value in addition to a unit (eg. meter, kilogram, volt, ampere, etc.). They are documented in depth in a [[PhysicalValues/en|separate part of this wiki]]. Physical values are created via unit operators.<br>For example, "50 volt" represents a voltage value of 50 volts.<br>Physical values values are not numbers, but can in most parts be treated like one (i.e. most arithmetic operations are supported).
These hold a number or measurement value in addition to a unit (e.g. meter, kilogram, volt, ampere, etc.). They are documented in depth in a [[PhysicalValues/en|separate part of this wiki]]. Physical values are created via unit operators.
<br>For example, "<CODE>50 volt</CODE>" represents a voltage value of 50 volts.<br>Physical values are not numbers, but can in most parts be treated like one (i.e. most arithmetic operations are supported).
100 volt * 3
100 volt * 3
yields "300 V". And:
yields "300 V". And:
100 volt * 0.1 ampere
100 volt * 0.1 ampere
yields "10 W" (watt).
yields "10 W" (watt). And:
10 volt / 2 ampere
yields "5 ohm".


Physical values can also be combined with measurement values:
Physical values can also be combined with measurement values:
100 volt ±% 3
100 volt ±% 3
represents a measured voltage with 3% possible error (i.e. "(100 ± 3) V"). And:
represents a measured voltage with 3% possible error (i.e. "(100 ± 3) V"). <br>And:
10 volt ± 2 volt
10 volt ± 2 volt
represents a measured voltage with 20% error (i.e. value in [8 .. 12] V")
represents a measured voltage with 20% error (i.e. value in [8 .. 12] V")

See details in the [[PhysicalValues/en|"Physical Values"]] document.


== Operations with Mixed Types ==
== Operations with Mixed Types ==


Normally, there is no need for explicit conversion between number types. The result of mixed operations is the computed with the type of the operand which has the higher "''generality''".
Normally, there is no need for explicit conversion between number types. The result of mixed operations is computed with the type of the operand which has the higher "''generality''". This conversion is called "''coercion''" - i.e. the operand with the lower generality is ''coerced'' into the type of the other before the operation is performed.

The order of generalities is:
The order of generalities is:
Integer < Fraction < ScaledDecimal < FixedDecimal
Integer < Fraction < ScaledDecimal < FixedDecimal
Zeile 231: Zeile 356:
<br>When either one is a complex, the result will also be.
<br>When either one is a complex, the result will also be.


When two floats are involved, the result will be generated with the higher precision.
==== MeasurementValues ====
Automatic conversion is also performed when MeasurementValues are involved:


But you should not be fooled by that: we do not get previously lost bits back, when a lower precision float is converted to a higher precision; the missing bits are simply assumed to be zero. In other words: "<CODE>ShortFloat pi asFloat</CODE>" will still only have roughly 7 digits of precision (which the original short float had), whereas "<CODE>Float pi</CODE>" will have its 15 digits.
''aMeasurementValue'' <code>+</code> ''aNumber'' => MeasurementValue
<br>''aMeasurementValue'' <code>-</code> ''aNumber'' => MeasurementValue
::the result will have the same error as the receiver. Eg. "(10 ± 1) + 10" yields "(20 ± 1)".


==== Mixed Operations with MeasurementValues ====
''aMeasurementValue'' <code>*</code> ''aNumber'' => MeasurementValue
Automatic conversion is also performed when MeasurementValues are involved:
<br>''aMeasurementValue'' <code>/</code> ''aNumber'' => MeasurementValue

::the error will also be scaled by ''aNumber''. Eg. "(10 ± 1) * 10" yields "(100 ± 10)".
:''aMeasurementValue'' '''+''' ''aNumber'' => MeasurementValue
:''aMeasurementValue'' '''-''' ''aNumber'' => MeasurementValue
::the result will have the same error as the receiver.
::E.g. (10 ± 1) + 10 => (20 ± 1).
&nbsp;
:''aMeasurementValue'' '''*''' ''aNumber'' => MeasurementValue
:''aMeasurementValue'' '''/''' ''aNumber'' => MeasurementValue
::the error will also be scaled by ''aNumber''.
::E.g. (10 ± 1) * 10 => (100 ± 10).
&nbsp;
&nbsp;


==== PhysicalValues ====
==== Mixed Operations with PhysicalValues ====
PhysicalValues can only be scaled by a scalar value; addition and subtraction are not allowed:
PhysicalValues can be scaled by a scalar or multiplied by another physical value (possibly resulting in a value with a different unit). Addition and subtraction are only allowed if the arguments have the same base type:


''aPhysicalValue'' <code>+</code> ''aNumber'' => error
:''aPhysicalValue'' '''+''' ''aNumber'' => error
<br>''aPhysicalValue'' <code>-</code> ''aNumber'' => error
:''aPhysicalValue'' '''-''' ''aNumber'' => error
::not allowed
::not allowed
&nbsp;


''aPhysicalValue'' <code>*</code> ''aNumber'' => aPhysicalValue
:''aPhysicalValue'' '''*''' ''aNumber'' => PhysicalValue
<br>''aPhysicalValue'' <code>/</code> ''aNumber'' => aPhysicalValue
:''aPhysicalValue'' '''/''' ''aNumber'' => PhysicalValue
::for example, "10 volt * 10" gives "100 volt".
::for example, <CODE>10 volt * 10</CODE> => <CODE>100 volt</CODE>,
::and <CODE>10 volt / 1000</CODE> => 10 milliVolt</CODE>
&nbsp;
&nbsp;


Zeile 258: Zeile 391:
=== Testing ===
=== Testing ===


''aNumber'' <code>isFinite</code> => Boolean
:''aNumber'' '''isNaN''' => Boolean
:''aNumber''.'''isNaN'''() (in JS syntax)
::Check if number is not infinity and not NaN:
::Check if number is NaN ("''Not a Number''"). Notice that there are multiple representations of "NaN": "<CODE>Float32 NaN</CODE>", "<CODE>Float64 NaN</CODE>" etc.<br>Therefore, you should not compare against NaN with an identity compare operations (i.e. you should use isNaN to test, not compare for identity against another NaN)
&nbsp;
&nbsp;


''aNumber'' <code>isInfinite</code> => Boolean
:''aNumber'' '''isFinite''' => Boolean
::Check if number is either positive infinity (INF) or negative infinity (-INF):
::Check if number is not infinity and not NaN. As with NaN, there are multiple such "infinities"; one in each float class.
&nbsp;
&nbsp;


''aNumber'' <code>isNaN</code> => Boolean
:''aNumber'' '''isInfinite''' => Boolean
::Check if number is NaN ("''Not a Number''"):
::Check if number is either positive infinity (INF) or negative infinity (-INF).
&nbsp;
&nbsp;


''aNumber'' <code>isInteger</code> => Boolean
:''aNumber'' '''isPositiveInfinity''' => Boolean
::Check if number is the positive infinity (+INF).
&nbsp;

:''aNumber'' '''isNegativeInfinity''' => Boolean
::Check if number is the negative infinity (-INF).
&nbsp;

:''aNumber'' '''isInteger''' => Boolean
::Check if number is an integral number.
::Check if number is an integral number.
&nbsp;
&nbsp;


''aNumber'' <code>isFraction</code> => Boolean
:''aNumber'' '''isFraction''' => Boolean
::Check if number is a fractional number.
::Check if number is a fractional number.
&nbsp;
&nbsp;


''aNumber'' <code>isComplex</code> => Boolean
:''aNumber'' '''isFloat''' => Boolean
::Check if number is any float number (Float32, Float64, Float128, etc.).
&nbsp;

:''aNumber'' '''exponent''' => Integer
::For floats only: returns the exponent, such that the number's value is:<br> "mantissa * (2 ^ exponent)".
&nbsp;

:''aNumber'' '''mantissa''' => Integer
::For floats only: returns the mantissa, such that the number's value is:<br> "mantissa * (2 ^ exponent)".
&nbsp;

:''aNumber'' '''precision''' => Integer
::For floats only: returns the number of bits in the number's mantissa.
&nbsp;

:''aNumber'' '''decimalPrecision''' => Integer
::For floats only: returns the number of digits in the number's mantissa.
&nbsp;

:''floatClass'' '''fmin''' => float
::For float classes only: returns the smallest representable (normalized) number of that class.<br>For example, "<CODE>FloatD fmin</CODE>" would return 2.2250738585072e-308. Any operation which would generate a smaller number will deliver -INF.
&nbsp;

:''floatClass'' '''fmax''' => float
::For float classes only: returns the largest representable number of that class.<br>For example, "<CODE>FloatD fmax</CODE>" would return 1.79769313486232e+308. Any operation which would generate a larger number will deliver +INF.
&nbsp;

:''floatClass'' '''emin''' / '''emax''' => integer
::For float classes only: returns the smallest and largest possible exponent representable by numbers of that class.<br>For example, "<CODE>FloatD emin</CODE>" would return -1022. Notice that this is the exponent of the power-of-two; the corresponding decimal min/max exponent can be computed by multiplying it by log10(2).
&nbsp;

:''aNumber'' '''isComplex''' => Boolean
::Check if number is a complex number.
::Check if number is a complex number.
&nbsp;
&nbsp;


''aNumber'' <code>negative</code> => Boolean
:''aNumber'' '''negative''' => Boolean
::same as <code>''aNumber'' < 0</code>
::same as <code>''aNumber'' < 0</code>
&nbsp;
&nbsp;


''aNumber'' <code>positive</code> => Boolean
:''aNumber'' '''positive''' => Boolean
::same as <code>''aNumber'' >= 0</code>
::same as <code>''aNumber'' >= 0</code>
&nbsp;
&nbsp;


''aNumber'' <code>strictlyPositive</code> => Boolean
:''aNumber'' '''strictlyPositive''' => Boolean
::same as <code>''aNumber'' > 0</code>
::same as <code>''aNumber'' > 0</code>
&nbsp;
&nbsp;


''anInteger'' <code>isPrime</code> => Boolean
:''anInteger'' '''isPrime''' => Boolean
::true if the number is a prime number
::true if the number is a prime number
&nbsp;
&nbsp;


''anInteger'' <code>isPowerOf2</code> => Boolean
:''anInteger'' '''isPowerOf2''' => Boolean
::true if there exists an n, such that 2ˆn equals the number
::true if there exists an n, such that 2ˆn equals the number
&nbsp;
&nbsp;


''anInteger'' <code>isPowerOf:</code>''b'' => Boolean
:''anInteger'' '''isPowerOf:''' ''b'' => Boolean
::true if there exists an n, such that bˆn equals the number
::true if there exists an n, such that bˆn equals the number
&nbsp;

''anInteger'' <code>nextPrime</code> => anInteger
<br>''anInteger'' <code>nextPowerOf2</code> => anInteger
&nbsp;
&nbsp;


=== Arithmetic ===
=== Arithmetic ===


''aNumber'' <code>+</code> ''aNumber'' => Number
:''aNumber'' '''+''' ''aNumber'' => Number
<br>''aNumber'' <code>-</code> ''aNumber'' => Number
:''aNumber'' '''-''' ''aNumber'' => Number
<br>''aNumber'' <code>*</code> ''aNumber'' => Number
:''aNumber'' '''*''' ''aNumber'' => Number
<br>''aNumber'' <code>/</code> ''aNumber'' => Number
:''aNumber'' '''/''' ''aNumber'' => Number
::The usual arithmetic operators.<br>
::The usual arithmetic operators.<br>
::All of the above allow operands of any number type, and will generate a result as appropriate. When dividing integers, an exact result is returned (either integer or fraction). If any of the arguments is inexact (i.e. a floating point number), the result will be inexact. If both are exact, the result will be exact. Fractional results are reduced to the greatest common divisor as denominator.
::All of the above allow operands of any number type, and will generate a result as appropriate. When dividing integers, an exact result is returned (either integer or fraction). If any of the arguments is inexact (i.e. a floating point number), the result will be inexact. If both are exact, the result will be exact. Fractional results are reduced to the greatest common divisor as denominator.
::[[Datei:point_right.png|20px]] Notice, that Smalltalk evaluates them left to right, without special precedences.<br>Thus you should always use parentheses to group expressions when there are two or more operators in an arithmetic expression.
::[[Datei:point_right.png|20px]] Notice, that Smalltalk evaluates them left to right, without special precedences.<br>Thus you should always use parentheses to group expressions when there are two or more operators in an arithmetic expression. It is good practice to use parentheses even in expressions where the evaluation order gives the correct result.
&nbsp;


''aNumber'' <code>**</code> ''aNumber'' => Number
:''aNumber'' '''**''' ''aNumber'' => Number
<br>''aNumber'' <code>raisedTo:</code> ''aNumber'' => Number
:''aNumber'' '''raisedTo:''' ''aNumber'' => Number
::exponentiation (raising to a power)
::exponentiation (raising to a power)
::Examples:
::Examples:
Zeile 332: Zeile 503:
=> 10.0
=> 10.0
</div>
</div>
&nbsp;


''aNumber'' <code>//</code> ''aNumber'' => Integer
:''aNumber'' '''//''' ''aNumber'' => Integer
<br>''aNumber'' <code>\\</code> ''aNumber'' => Integer
:''aNumber'' '''\\''' ''aNumber'' => Integer
::Truncated result and remainder (towards the next smaller integer i.e. towards negative infinity).<br>The following equation holds: <code>(a // b) * b + (a \\ b) = a</code>
::Truncated result and remainder (towards the next smaller integer i.e. towards negative infinity).<br>The following equation holds: <code>(a // b) * b + (a \\ b) = a</code>
::Examples:
::Examples:
Zeile 348: Zeile 520:
=> 2
=> 2
</div>
</div>
&nbsp;
''aNumber'' <code>quo:</code> ''aNumber'' => Integer

<br>''aNumber'' <code>rem:</code> ''aNumber'' => Integer
:''aNumber'' '''quo:''' ''aNumber'' => Integer
:''aNumber'' '''rem:''' ''aNumber'' => Integer
::Truncated result (towards zero) and corresponding remainder.<br>For positive arguments, this is the same as the above, for negative args, a different result is returned.<br>However, the equation is similar to above: <code>(a quo: b) * b + (a rem: b) = a</code>
::Truncated result (towards zero) and corresponding remainder.<br>For positive arguments, this is the same as the above, for negative args, a different result is returned.<br>However, the equation is similar to above: <code>(a quo: b) * b + (a rem: b) = a</code>
::Examples:
::Examples:
Zeile 363: Zeile 537:
=> -1
=> -1
</div>
</div>
&nbsp;

:''aNumber'' '''abs''' => Number
::the absolute value.

:''aNumber'' '''negated''' => Number
::the negated value.


=== Mathematical and Trigonometric Functions ===
=== Mathematical and Trigonometric Functions ===
The usual operations are provided as unary messages to the number:
The usual operations are provided as unary messages to the number:


<br>''aNumber'' <code>ln</code> => Number
:''aNumber'' '''ln''' => Number
<br>''aNumber'' <code>log10</code> => Number
:''aNumber'' '''log10''' => Number
<br>''aNumber'' <code>log2</code> => Number
:''aNumber'' '''log2''' => Number
<br>''aNumber'' <code>log:</code>''base'' => Number
:''aNumber'' '''log:''' ''base'' => Number
:''aNumber'' '''integerLog10''' => Integer
:logarithm (natural, base10, base2 or arbitrary base).
:''aNumber'' '''integerLog2''' => Integer
:These are not restricted to floats; they can also be applied to big integers,<br>as in:<code>1000 factorial ln</code>
::logarithm (natural, base10, base2 or arbitrary base).
:By default, an error is reported for negative numbers;
:to get a complex result, use "<code>Complex trapImaginary:[ aNumber ln ]</code>".
::These are not restricted to floats; they can also be applied to big integers,<br>as in: "<code>1000 factorial ln</code>".
::By default, an error is reported for negative numbers;
::to get a complex result, use "<code>Complex trapImaginary:[ aNumber ln ]</code>".
&nbsp;
&nbsp;


''aNumber'' <code>sqrt</code> => Number
:''aNumber'' '''sqrt''' => Number
<br>''aNumber'' <code>integerSqrt</code> => Number
:''anInteger'' '''integerSqrt''' => Integer
: square root and truncated square root<br>By default, an error is reported for negative numbers;<br>to get a complex result, use "<code>Complex trapImaginary:[ aNumber sqrt ]</code>".
::square root and truncated square root<br>By default, an error is reported for negative numbers;<br>to get a complex result, use "<code>Complex trapImaginary:[ aNumber sqrt ]</code>".
&nbsp;
&nbsp;


''aNumber'' <code>cbrt</code> => Number
:''aNumber'' '''cbrt''' => Number
<br>''aNumber'' <code>integerCbrt</code> => Number
:''anInteger'' '''integerCbrt''' => Integer
: cubic root and truncated cubic root.
::cubic root and truncated cubic root.
&nbsp;
&nbsp;


''aNumber'' <code>exp</code> => Number
:''aNumber'' '''nthRoot:''' ''n'' => Number
::the nth root.<br>"<code>n nthRoot:2</code>" gives the same result as "<code>sqrt</code>"<br>and "<code>n nthRoot:3</code>" the same as the cubic root.
<br>''number1'' <code>raisedTo:</code>''number2'' => Number
<br>''number1'' <code>**</code>''number2'' => Number
: exponentiation; the "**" binary operator is an alias for "raisedTo:".
&nbsp;
&nbsp;


''aNumber'' <code>sin</code> => Number
:''aNumber'' '''exp''' => Number
<br>''aNumber'' <code>cos</code> => Number
:''number1'' '''raisedTo:''' ''number2'' => Number
<br>''aNumber'' <code>tan</code> => Number
:''number1'' '''**''' ''number2'' => Number
::exponentiation; the "<code>**</code>" binary operator is an alias for "<code>raisedTo:</code>".
<br>''aNumber'' <code>cot</code> => Number (cotangent)
&nbsp;
<br>''aNumber'' <code>sec</code> => Number (secant)

<br>''aNumber'' <code>csc</code> => Number (cosecant)
<br>''aNumber'' <code>arcSin</code> => Number
:''aNumber'' '''sin''' => Number
<br>''aNumber'' <code>arcCos</code> => Number
:''aNumber'' '''cos''' => Number
<br>''aNumber'' <code>arcTan</code> => Number
:''aNumber'' '''tan''' => Number
<br>''aNumber'' <code>arcTan2:</code>''x'' => Number
:''aNumber'' '''cot''' => Number (cotangent)
:''aNumber'' '''sec''' => Number (secant)
:trigonometric functions
:''aNumber'' '''csc''' => Number (cosecant)
:''aNumber'' '''arcSin''' => Number
:''aNumber'' '''arcCos''' => Number
:''aNumber'' '''arcTan''' => Number
:''aNumber'' '''arcTan2:''' ''x'' => Number
::trigonometric functions
&nbsp;

:''aNumber'' '''sinh''' => Number
:''aNumber'' '''cosh''' => Number
:''aNumber'' '''tanh''' => Number
:''aNumber'' '''arSinh''' => Number
:''aNumber'' '''arCosh''' => Number
:''aNumber'' '''arTanh''' => Number
::hyperbolic functions

=== Truncation and Rounding ===
:''aNumber'' '''ceiling''' => Number
::returns the next larger integer (unless aNumber is integral).<br>E.g. truncates towards positive infinity.

:''aNumber'' '''floor''' => Number
::returns the next smaller integer (unless aNumber is integral).<br>E.g. truncates towards negative infinity.

:''aNumber'' '''truncated''' => Integer
::truncates towards zero

:''aNumber'' '''truncateTo:''' ''grid'' => Number
::truncates towards the nearest multiple of ''grid''. <br>E.g. "<code>1.284 truncateTo:0.1</code>" yields "1.2".

:''aNumber'' '''rounded''' => Number
::rounds up/down towards the nearest integer

:''aNumber'' '''roundTo:''' ''grid'' => Number
::rounds up/down towards the nearest multiple of ''grid''. <br>E.g. "<code>1.284 roundTo:0.1</code>" yields "1.3" and "<code>523 roundTo:5</code>" yields "525".

:''aNumber'' '''roundToNumberOfDigits:''' ''n'' => Number
::rounds up/down for n valid digits. <br>E.g. "<code>1.284 roundToNumberOfDigits:2</code>" yields "1.3" and "<code>5234 roundToNumberOfDigits:2</code>" yields "5200".

:''aNumber'' '''roundToPrecision:''' ''n'' => Number
::rounds up/down for n decimal fraction digits. <br>E.g. "<code>1.284 roundToPrecision:2</code>" yields "1.28" and "<code>5234.356 roundToPrecision:2</code>" yields "5234.36".

=== Statistical / Combinatorical Functions ===

:''anInteger'' '''factorial''' => Integer
::the factorial; i.e. "<code>n factorial</code>" is 2*3*4...*n". Huge numbers are to be expected (try "<code>1000 factorial inspect</code>" in a workspace).

:''n'' '''binomialCoefficient:''' ''k'' => Integer
:''n'' '''binco:''' ''k'' => Integer
::the binomial coefficient (aka. ''n over k'' or the number of ways of picking k unordered outcomes from n possibilities)

:''n'' '''agm:''' ''y'' => Float
::the arithmetic-geometric mean

=== Other Special Functions ===

:''integer1'' '''gcd:''' ''integer2'' => Integer
::the greatest common divisor of integer1 and integer2.

:''integer1'' '''lcm:''' ''integer2'' => Integer
::the least common multiple of integer1 and integer2.

:''anInteger'' '''fib''' => Integer
::the nth Fibonacci number. Huge numbers are to be expected (try "<code>1000 fib inspect</code>" in a workspace).

:''aNumber'' '''fib_binet''' => Float
::an approximation of the nth Fibonacci number according to Binet.<br>For example, "<code>5000 fib_binet</code>" gives: "1.0777734893072974780...e+10449" (by default with 200 bits precision)

:''aNumber'' '''erf''' => Float
::the error function

:''aNumber'' '''gamma''' => Float
::the gamma function

:''anInteger'' '''nextPrime''' => Integer
::the next prime number.


:''anInteger'' '''primeFactors''' => Collection
<br>''aNumber'' <code>sinh</code> => Number
::the prime factors. Can take a long time for big numbers.
<br>''aNumber'' <code>cosh</code> => Number
<br>''aNumber'' <code>tanh</code> => Number
<br>''aNumber'' <code>arSinh</code> => Number
<br>''aNumber'' <code>arCosh</code> => Number
<br>''aNumber'' <code>arTanh</code> => Number
:hyperbolic functions


=== Bitwise Operators ===
=== Bitwise Operators ===


''integer1'' <code>bitAnd:</code>''integer2'' => Integer
:''integer1'' '''bitAnd:''' ''integer2'' => Integer
<br>''integer1'' <code>bitOr:</code>''integer2'' => Integer
:''integer1'' '''bitOr:''' ''integer2'' => Integer
<br>''integer1'' <code>bitXor:</code>''integer2'' => Integer
:''integer1'' '''bitXor:''' ''integer2'' => Integer
::bitwise and, or and exclusive or
<br>''integer1'' <code>bitShift:</code>''count'' => Integer
:''integer1'' '''bitShift:''' ''count'' => Integer
:left shift if count is positive; right shift if negative
::left shift if count is positive; right shift if negative
<br>''integer1'' <code>leftShift:</code>''count'' => Integer
<br>''integer1'' <code>rightShift:</code>''count'' => Integer
:''integer1'' '''leftShift:''' ''count'' => Integer
::left shift by count
<br>''integer1'' <code>bitTest:</code>''integer2'' => Boolean
:''integer1'' '''rightShift:''' ''count'' => Integer
:integer2 is used as a ''mask'' (i.e. bitTest returns true if any bit in the mask is set in the left operand i.e. (i1 & i2) not equal 0
::right shift by count
<br>''integer1'' <code>bitAt:</code>''bitNr'' => integer (0 or 1)
:''integer1'' '''bitTest:''' ''integer2'' => Boolean
:extract the nth bit, with bitNr starting at 1
::integer2 is used as a ''mask'' (i.e. bitTest returns true if any bit in the mask is set in the left operand i.e. (i1 & i2) not equal 0
<br>''integer'' <code>highBit</code> => integer (1..)
:''integer1'' '''bitAt:''' ''bitNr'' => integer (0 or 1)
:the bit number of the highest bit, with bitNr starting at 1; zero if no bit is set
::extract the nth bit, with bitNr starting at 1
<br>''integer'' <code>lowBit</code> => integer (1..)
:''integer1'' '''lowBits:''' ''count'' => integer
:the bit number of the lowest bit, with bitNr starting at 1; zero if no bit is set
::extract count lowest bits
:''integer'' '''highBit''' => integer (1..)
::the bit number of the highest bit, with bitNr starting at 1; zero if no bit is set
:''integer'' '''lowBit''' => integer (1..)
::the bit number of the lowest bit, with bitNr starting at 1; zero if no bit is set


=== Printing ===
=== Printing ===
Zeile 435: Zeile 691:
Numbers can print themself on an output stream, or convert themself to a string:
Numbers can print themself on an output stream, or convert themself to a string:


''aNumber'' <code>printOn:</code>''aStream'' => void
:''aNumber'' '''printOn:''' ''aStream'' => void
<br>''aNumber'' <code>printOn:</code>''aStream'' <code>radix:</code>''base'' => void
:''aNumber'' '''printOn:''' ''aStream'' '''radix:''' ''base'' => void
<br>''aNumber'' <code>printOn:</code>''aStream'' <code>leftPaddedTo:</code>''length'' => void
:''aNumber'' '''printOn:''' ''aStream'' '''leftPaddedTo:''' ''length'' => void
<br>''aNumber'' <code>printOn:</code>''aStream'' <code>leftPaddedTo:</code>''length'' <code>with:</code>''padCharacter'' => void
:''aNumber'' '''printOn:''' ''aStream'' '''leftPaddedTo:''' ''length'' '''with:''' ''padCharacter'' => void
<br>''aNumber'' <code>printOn:</code>''aStream'' <code>paddedTo:</code>''length'' => void
:''aNumber'' '''printOn:''' ''aStream'' '''paddedTo:''' ''length'' => void
<br>''aNumber'' <code>printOn:</code>''aStream'' <code>paddedTo:</code>''length'' <code>with:</code>''padCharacter'' => void
:''aNumber'' '''printOn:''' ''aStream'' '''paddedTo:''' ''length'' '''with:''' ''padCharacter'' => void
<br>''aNumber'' <code>printString</code> => String
:''aNumber'' '''printString''' => String
<br>''aNumber'' <code>printStringRadix:</code>''base'' => String
:''aNumber'' '''printStringRadix:''' ''base'' => String
<br>''aNumber'' <code>printStringLeftPaddedTo:</code>''length'' => String
:''aNumber'' '''printStringLeftPaddedTo:''' ''length'' => String
<br>''aNumber'' <code>printStringLeftPaddedTo:</code>''length'' <code>with:</code>''padCharacter'' => String
:''aNumber'' '''printStringLeftPaddedTo:''' ''length'' '''with:''' ''padCharacter'' => String
<br>''aNumber'' <code>printStringPaddedTo:</code>''length'' => String
:''aNumber'' '''printStringPaddedTo:''' ''length'' => String
<br>''aNumber'' <code>printStringPaddedTo:</code>''length'' <code>with:</code>''padCharacter'' => String
:''aNumber'' '''printStringPaddedTo:''' ''length'' '''with:''' ''padCharacter'' => String
::The above generate a standard format, which should fit most needs. The padded variants fill with either space or the explicit padCharacter. The printOn: variants will send the string to an output stream; the printString variants will return the string.
::The above generate a standard format, which should fit most needs. The padded variants fill with either space or the explicit padCharacter. The printOn: variants will send the string to an output stream; the printString variants will return the string.
&nbsp;


<br>''formatString'' <code>printf:</code> { ''arg''... } <code>on:</code> ''aStream'' => void
:''formatString'' '''printf:''' { ''arg''... } '''on:''' ''aStream'' => void
<br>''formatString'' <code>printf:</code> { ''arg''... } => String
:''formatString'' '''printf:''' { ''arg''... } => String
::More fine control is available via the printf functions, which also offer a range of options to fill left or right, to control printing of the sign and to fill with zeros.
::More fine control is available via the printf functions, which also offer a range of options to fill left or right, to control printing of the sign and to fill with zeros.
::These two interpret the receiver as a C-printf-style format string, and an argument vector as first argument (use a [[Smalltalk_Syntax_Cheat_Sheet#Expressions | brace-array constructor]] or pass a collection as argument).<br>Thus, multiple values are printed as in the following example:
::These two interpret the receiver as a C-printf-style format string, and an argument vector as first argument (use a [[Smalltalk_Syntax_Cheat_Sheet#Expressions | brace-array constructor]] or pass a collection as argument).<br>Thus, multiple values are printed as in the following example:
Zeile 458: Zeile 715:
::Individual conversions (to a string) can also be done with:
::Individual conversions (to a string) can also be done with:
<div style="margin-left: 3em;">
<div style="margin-left: 3em;">
''aNumber'' <code>printfPrintString:</code>''formatString'' => String
''aNumber'' '''printfPrintString:''' ''formatString'' => String
</div>
</div>
::Examples:
::Examples:
Zeile 467: Zeile 724:
'%+.4f' printf:{Float pi negated} => '-3.1416' ('+' after % enforces sign)
'%+.4f' printf:{Float pi negated} => '-3.1416' ('+' after % enforces sign)
</div>
</div>
:: Please refer to a C-printf manual page (eg. https://en.wikipedia.org/wiki/Printf_format_string).
:: Please refer to a C-printf manual page (e.g. https://en.wikipedia.org/wiki/Printf_format_string).
:: Notice that printf accepts C-style character escapes (which is not the case in general with Smalltalk string constants)
:: Notice that printf accepts C-style character escapes (which is not the case in general with Smalltalk string constants)
&nbsp;

:''aNumber'' '''printRomanOn:''' ''aStream'' => void
::roman style


=== Reading from Streams / Converting from Strings ===
=== Reading from Streams / Converting from Strings ===


Numbers can be read from a stream or converted from a string. There are slight differences between them:
Numbers can be read from a stream or converted from a string. There are slight differences between them:
* when reading from a stream of characters, the stream will be positioned after the number. So any non-digit character(s) after the number's characters will be returned by future read operations.
* when reading from a stream of characters, the stream will be positioned after the number. So any non-digit character(s) after the number's characters will be returned by future read operations. The stream can be an internal or external (i.e. file-, pipe- or socket-) stream.
* when converting from a string, no extra characters are expected/allowed after the number's digits, except for whitespace. Thus you'll usually get an error when trying to convert a string with garbage characters after the number (which is not the case when reading from a stream).
* when converting from a string, no extra characters are expected/allowed after the number's digits, except for whitespace. Thus you'll usually get an error when trying to convert a string with garbage characters after the number (which is not the case when reading from a stream).


Therefore, if you want to read a number from a string which may habe garbage characters after the digits, you should first create a read-stream on the string, and then read the number from the stream (i.e. "Number readFrom:(''someString'' readStream). instead of "Number fromString:''someString''"
Therefore, if you want to read a number from a string which may have garbage characters after the digits, you should first create a read-stream on the string, and then read the number from the stream (i.e. use "<code>Number readFrom:(''someString'' readStream)</code>" instead of "<code>Number fromString:''someString''</code>").


Numbers are read by sending the Number-class a "readFrom:" or a "fromString:" message.
Numbers are read by sending the Number-class or one of its subclasses one of the "<code>readFrom:</code>" or "<code>fromString:</code>" messages.

If the class is the abstract class Number, then the read code will itself figure out, what kind of number to return. If the given class is a concrete class (Float, Integer, Fraction etc.), you will get an instance of that class, unless the characters o not represent a valid number (of that class).
If the class is the abstract class Number, then the read code will itself figure out, what kind of number to return. If the class is a concrete class (Float, Integer, Fraction etc.), you will get an instance of that class, unless the characters do not represent a valid number (of that class). In that case, an error is reported.
In that case, an error is reported.


By default, errors are reported by raising an exception, unless you provide an error-handler as argument to the reader; more on that below.
By default, errors are reported by raising an exception, unless you provide an error-handler as argument to the reader; more on that below.
<code>Number readFrom:</code> ''aStream'' => someNumber or error
:Number '''readFrom:''' ''aStream'' => someNumber or error
:: this can return any of the number types
:: this can return an instance of any of the number types
<br><code>Number readFrom:</code> ''aStream'' <code>onError:</code>[ ''errorValue'' ] => someNumber or errorValue
:Number '''readFrom:''' ''aStream'' '''onError:'''[ ''errorValue'' ] => someNumber or errorValue
:: errorValue (which is a Smalltalk block), can be a constant, an arbitrary Smalltalk expression or even show a warn dialog or do whatever you like
:: errorValue can be a constant, an arbitrary Smalltalk expression or even show a warn dialog or do whatever you like. In case of an error, the value returned from the read method will be the value provided by the error-block. Notice, that numbers themself respond to the <code>value</code> message and will return themself. Thus you can also provide a replacement value instead of an error block.
<code>Number fomString:</code> ''aString'' => someNumber or error
:Number '''fromString:''' ''aString'' => someNumber or error
<br><code>Number fromString:</code> ''aString'' <code>onError:</code>[ ''errorValue'' ]</code> => someNumber or fallBackValue
:Number '''fromString:''' ''aString'' '''onError:'''[ ''errorValue'' ]</code> => someNumber or fallBackValue
:: similar, but does not allow for garbage characters after the number (except spaces)


<code>Integer readFrom:</code> ''aStream''
:Integer '''readFrom:''' ''aStream''
<code>Integer readFrom:</code> ''aStream'' <code>onError:[...]</code>
:Integer '''readFrom:''' ''aStream'' '''onError:'''[...]
<br><code>Float readFrom:</code> ''aStream''
:Float '''readFrom:''' ''aStream''
<br><code>Float readFrom:</code> ''aStream'' <code>onError:[...]</code>
:Float '''readFrom:''' ''aStream'' '''onError:'''[...]
<br><code>Integer fromString:</code> ''aStream''
:Integer '''fromString:''' ''aStream''
<br><code>Integer fromString:</code> ''aStream'' <code>onError:[...]</code>
:Integer '''fromString:''' ''aStream'' '''onError:'''[...]
<br><code>Float fromString:</code> ''aStream''
:Float '''fromString:''' ''aStream''
<br><code>Float fromString:</code> ''aStream'' <code>onError:[...]</code>
:Float '''fromString:''' ''aStream'' '''onError:'''[...]
:: similar, but these will return a corresponding typed number
:: similar to the above, but these will return a correspondingly typed number (i.e. an instance of Integer, Float, etc.


''formatString'' sscanf: ''aString'' => collection
:''formatString'' '''sscanf:''' ''aString'' => collection
:: ''formatString'' is a printf/scanf-like format string; reads items from ''aString'' and returns a collection (i.e. an Array) of scanned objects.<br>For example,<br><code> '%d %x %f' sscanf: '1234 FF 3.1415'</code><br>will return an array-like collection with 3 elements, the integer 1234, the integer 255 and the float 3.14159.
:: ''formatString'' is a printf/scanf-like format string; reads items from ''aString'' and returns a collection (i.e. an Array) of scanned objects.<br>For example,<br><code> '%d %x %f' sscanf: '1234 FF 3.1415'</code><br>will return an array-like collection with 3 elements, the integer 1234, the integer 255 and the float 3.14159.


''formatString'' scanf: ''aStream'' => collection
:''formatString'' '''scanf:''' ''aStream'' => collection
:: like above, but the elements will be read from a character stream
:: like above, but the elements will be read from a character stream


:To read binary numbers, refer to the stream API.
=== Truncation and Rounding ===
<br>''aNumber'' <code>truncated</code> => Integer
::truncates towards zero

<br>''aNumber'' <code>rounded</code> => Number
::rounds up/down towards the nearest integer

<br>''aNumber'' <code>ceiling</code> => Number
::returns the next larger integer (unless aNumber is integral). I.e. truncates towards positive infinity.


=== Conversion ===
<br>''aNumber'' <code>floor</code> => Number
::returns the next smaller integer (unless aNumber is integral). I.e. truncates towards negative infinity.


In certain situations, it may be desirable to convert explicitly to a particular type, for example when binary data has to be verified or filled into a byte-buffer.
<br>''aNumber'' <code>roundTo:</code> ''grid'' => Number
::rounds up/down towards the nearest multiple of ''grid''. I.e. "1.284 roundedTo:0.1" yields "1.3".


<br>''aNumber'' <code>truncateTo:</code> ''grid'' => Number
:''aNumber'' '''asInteger''' => Integer
::truncates towards the nearest multiple of ''grid''. I.e. "1.284 truncateTo:0.1" yields "1.2".
::truncates to an integer (i.e. same as "truncated")


:''aNumber'' '''asFloat''' => Float64
=== Conversion ===
:''aNumber'' '''asFloat64''' => Float64

:''aNumber'' '''asFloatD''' => Float64
In certain situations, it may be desirable to convert explicitly to a particular type, for example when binary data has to be verified or filled into a byte-buffer.
::generates a double precision float; may generate +/- INF if the value cannot be represented as a double IEEE float (i.e. is out of range). asFloat64 and asFloatD are aliases for compatibility.
:''aNumber'' '''asFloatChecked''' => Float64 or error
::same as above, but reports an error if the value cannot be represented (instead of returning INF).


<br>''aNumber'' <code>asInteger</code> => Integer
:''aNumber'' '''asShortFloat''' => Float32
:''aNumber'' '''asFloat32''' => Float32
::truncates (i.e. same as "truncated")
<br>''aNumber'' <code>asFloat</code> => Float64
:''aNumber'' '''asFloatE''' => Float32
::generates double precision float; may generate +/- INF if the value cannot be represented as a double IEEE float (i.e. is out of range).
::generates a single precision float; may generate +/- INF if the value cannot be represented as a single IEEE float. asFloat32 and asFloatE are aliases.
<br>''aNumber'' <code>asFloatChecked</code> => Float64 or error
:''aNumber'' '''asShortFloatChecked''' => Float32 or error
::same as above, but generates an error if the value cannot be represented.
::same as above, but reports an error if the value cannot be represented (instead of returning INF).
<br>''aNumber'' <code>asShortFloat</code> => Float32
:''aNumber'' '''asLongFloat''' => Float80
:''aNumber'' '''asFloatQ''' => Float80
::generates single precision float; may generate +/- INF if the value cannot be represented as a single IEEE float.
<br>''aNumber'' <code>asShortFloatChecked</code> => Float32 or error
::same as above, but generates an error if the value cannot be represented.
<br>''aNumber'' <code>asLongFloat</code> => Float80
::generates an extended precision float; may generate +/- INF if the value cannot be represented as an extended IEEE float.
::generates an extended precision float; may generate +/- INF if the value cannot be represented as an extended IEEE float.
<br>''aNumber'' <code>asLongFloatChecked</code> => Float80 or error
:''aNumber'' '''asLongFloatChecked''' => Float80 or error
::same as above, but generates an error if the value cannot be represented.
::same as above, but reports an error if the value cannot be represented (instead of returning INF).
<br>''aNumber'' <code>asQDouble</code> => QDouble
:''aNumber'' '''asQDouble''' => QDouble
::generates a qDouble (from a float or integer)
::generates a qDouble
<br>''aNumber'' <code>asQuadFloat</code> => QuadFloat
:''aNumber'' '''asQuadFloat''' => QuadFloat
:''aNumber'' '''asFloat128''' => QuadFloat
::generates a quadruple precision float (from a float or integer)
::generates a quadruple precision float (float128)
<br>''aNumber'' <code>asOctaFloat</code> => OctaFloat
:''aNumber'' '''asOctaFloat''' => OctaFloat
::generates an octuple precision float (from a float or integer)
<br>''aNumber'' <code>asFraction</code> => Fraction
:''aNumber'' '''asFloat256''' => QuadFloat
::generates an octuple precision float (float256)
:''aNumber'' '''asLargeFloatPrecision:''' ''numBits'' => LargeFloat
::generates an large float with numBits precision
:''aNumber'' '''asLargeFloatDecimalPrecision:''' ''numDigits'' => LargeFloat
::generates an large float with numDigits precision
:''aNumber'' '''asLargeFloat''' => LargeFloat
::generates an large float with the same precision as aNumber
:''aNumber'' '''asFraction''' => Fraction
::generates a fraction (from a float)
::generates a fraction (from a float)
<br>''aNumber'' <code>asScaledDecimal:</code> ''scale'' => ScaledDecimal
:''aNumber'' '''asScaledDecimal:''' ''scale'' => ScaledDecimal
::generates a scaled decimal which presents ''scale'' fractional digits
::generates a scaled decimal which presents ''scale'' fractional digits
<br>''aNumber'' <code>asFixedDecimal:</code> ''scale'' => FixedDecimal
:''aNumber'' '''asFixedDecimal:''' ''scale'' => FixedDecimal
::generates a fixed decimal which rounds on and presents ''scale'' fractional digits
::generates a fixed decimal which rounds on and presents ''scale'' fractional digits
<br>''aNumber'' <code>asComplex</code> => Complex
:''aNumber'' '''asComplex''' => Complex
::generates a complex (with 0 as imaginary part, same as "''nr'' + 0i")
::generates a complex (with 0 as imaginary part, same as "''nr'' + 0i")
:''aNumber'' '''i''' => Complex (that is a lower case i)
::generates a complex (with 0 as real part, e.g. as in "0 + ''nr'' i")


== Examples ==
== Examples ==


Square root of 2 with different precision:
==== Square root of 2 with different precision ====
nr := 2.0 sqrt.
nr := 2.0 sqrt.
'%.15g' printf:{nr}
=> '1.4142135623731'
'%.30g' printf:{nr}
'%.30g' printf:{nr}
-> '1.414213562373095101065700873732' (a float)
=> '1.414213562373095101065700873732'
'%.50g' printf:{nr}
'%.50g' printf:{nr}
-> '1.41421356237309510106570087373256683349609375'
=> '1.41421356237309510106570087373256683349609375'
Be reminded that these floats (which are IEEE doubles) only provide 15 digits of accuracy ("Float decimalPrecision" returns 15).
Be reminded that these floats (which are IEEE doubles) only provide 15 digits of accuracy ("Float decimalPrecision" returns 15). Thus the above attempts to generate more digits are useless and excess digits are more or less random.

<br>More valid digits are returned by QDoubles ("QDouble decimalPrecision" returns 61):
More valid digits are returned by QDoubles ("QDouble decimalPrecision" returns 61):
nr := 2.0 asQDouble sqrt.
nr := 2.0 asQDouble sqrt.
'%.30g' printf:{nr}
'%.30g' printf:{nr}
-> '1.41421356237309504880168872421' (roughly 200 bits precision)
=> '1.41421356237309504880168872421'
'%.50g' printf:{nr}
'%.50g' printf:{nr}
-> '1.4142135623730950488016887242096980785696718753769'
=> '1.4142135623730950488016887242096980785696718753769'
'%.100g' printf:{nr}
'%.100g' printf:{nr}
-> '1.414213562373095048801688724209698078569671875376948073176679737988424424484343089516915416653038211'
=> '1.414213562373095048801688724209698078569671875376948073176679737988424424484343089516915416653038211'
Here again, digits after the 60th are wrong.
or with octuple precision floats ("OctaFloat decimalPrecision" returns 71):

With octuple precision floats ("OctaFloat decimalPrecision" returns 71) we get:
nr := 2.0 asOctaFloat sqrt.
nr := 2.0 asOctaFloat sqrt.
'%.30g' printf:{nr}
'%.30g' printf:{nr}
-> '1.41421356237309504880168872421' (a quadruple precision float)
=> '1.41421356237309504880168872421' (a quadruple precision float)
'%.50g' printf:{nr}
'%.50g' printf:{nr}
-> '1.4142135623730950488016887242096980785696718753769'
=> '1.4142135623730950488016887242096980785696718753769'
'%.100g' printf:{nr}
'%.100g' printf:{nr}
-> '1.41421356237309504880168872420969807856967187537694807317667973799073247801160833747418698891953623'
=> '1.41421356237309504880168872420969807856967187537694807317667973799073247801160833747418698891953623'

Finally, an arbitrary number of digits can be computed with LargeFloats (here 1000 bits for roughly 300 digits precision):
Finally, an arbitrary number of digits can be computed with LargeFloats (here we use a precision of 1000 bits for roughly 300 digits):
nr := (2.0 asLargeFloatPrecision:1000) sqrt.
nr := (2.0 asLargeFloatPrecision:1000) sqrt.
'%.30g' printf:{nr}
'%.30g' printf:{nr}
-> '1.41421356237309504880168872421'
=> '1.41421356237309504880168872421'
'%.50g' printf:{nr}
'%.50g' printf:{nr}
-> '1.4142135623730950488016887242096980785696718753769'
=> '1.4142135623730950488016887242096980785696718753769'
'%.100g' printf:{nr}
'%.100g' printf:{nr}
-> '1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573'
=> '1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573'

In most situations, double precision is sufficient. However, some computations generate intermediate results which are outside the precision or range of IEEE doubles. See "[[Do not trust Floating Point]]" for a classic (surprising) example.


==== Reading Numbers ====

readFrom: will not accept garbage characters after the number iff the argument is a string:
in := '123.456abc'.
Number readFrom: in.
=> error due to garbage after number ('abc')

However, it behaves different, if the argument is a stream.<br>Then the stream will be left positioned after the number's string:
Number readFrom: (in readstream).
=> 123.456
(stream will be left positioned at the 'abc')

here, reading the rest after the number's digits:
s := in readstream.
val := Number readFrom: s.
rest := s upToEnd.
=> val: 123.456
rest: 'abc'

you can provide an error-value:
val := Number readFrom:'bla' onError:[0]
=> val: 0

or perform any action inside the onError arg block:
val := Number readFrom:'blabla' onError:[ Dialog warn:'bad input'. nil ]
=> (Dialog shown)
val: nil

an alternative to "readFrom:" is scanf, which can also read multiple values from a stream:
row := '%d %f %s' scanf:(ReadStream on:'1234 1111.2345 Fritz').
=> OrderedCollection(1234 1111.2345 'Fritz')
i.e. an integer, a float and a string

or from a string:
myString := '1234 1111.2345 Fritz'.
row := '%d %f %s' scanf: myString.
=> OrderedCollection(1234 1111.2345 'Fritz')
i.e. same as above

scanf can also be used to extract numbers which are not delimited by spaces (you have to specify the field length in the format):
myString := '1.234.5679875679'.
'%4f %5f %3d %4d' scanf:myString
=> OrderedCollection(1.23 4.567 987 5679)


== Printf Format Specifier ==
== Printf Format Specifier ==
Zeile 603: Zeile 918:
* required: character describing output behavior (POSIX: <<conversion specifier>>)
* required: character describing output behavior (POSIX: <<conversion specifier>>)


The format follows the ''official'' C-library printf formats; however, there were differences in
The format follows the ''official'' C-library printf formats; however, there are differences in
the various printf implementations:
the various printf implementations:
ANSI standards up through C99:
ANSI standards up through C99:
* more flags '+' ' ' '0' '#'
* more flags: '+' ' ' '0' '#'
* more lengths 'L' 'hh' 'll' 'j' 'z' 't'
* more lengths: 'L' 'hh' 'll' 'j' 'z' 't'
* more conversions 'F' 'a' 'A' 'n'
* more conversions: 'F' 'a' 'A' 'n'


The POSIX specification of printf added:
The POSIX specification of printf added:
* positional parameters to identify argument indices
* positional parameters to identify argument indices
* more flags ''' (single quote)
* more flags: ''' (single quote)
* more conversions 'C' 'S'
* more conversions: 'C' 'S'
* clarifications regarding corner cases and 'undefined behavior'
* clarifications regarding corner cases and 'undefined behavior'


BSD implementations added:
BSD implementations added:
* more lengths 'q'
* more lengths: 'q'
* more conversions 'D' 'U' 'O'
* more conversions: 'D' 'U' 'O'


glibc (GNU) added:
glibc (GNU) added:
* more lengths 'Z'
* more lengths: 'Z'
* more conversions 'm'
* more conversions: 'm'


Windows C Runtime (CRT) added:
Windows C Runtime (CRT) added:
* more lengths 'I' 'I32' 'I64' 'w'
* more lengths: 'I' 'I32' 'I64' 'w'


glibc and CRT both added length 'Z'.
glibc and CRT both added length 'Z'.
Zeile 632: Zeile 947:
* CRT uses Z as a conversion for length-prefixed strings.
* CRT uses Z as a conversion for length-prefixed strings.


The Smalltalk implementation takes the former approach, handling 'Z' in the same way as 'z'.
The expecco/Smalltalk implementation handles 'Z' in the same way as 'z'.


BSD and IBM C library both added 'D'.
BSD and IBM C library both added 'D'.
Zeile 640: Zeile 955:
The Smalltalk implementation takes the former approach.
The Smalltalk implementation takes the former approach.


The Smalltalk implementation also adds new conversions:
The expecco/Smalltalkimplementation also adds new conversions:


* 'b' and 'B' for binary (base-2) integer renderings
* 'b' and 'B' for binary (base-2) integer renderings
* 'y' and 'Y' for true/false and yes/no Boolean conversions
* 'y' and 'Y' for true/false and yes/no Boolean conversions
* 'J' for JSON
* 'J' for JSON (assuming that the object can be JSON-encoded)
* 'T' and 'V' for JS typeof and valueOf inspection
* 'T' and 'V' for JS typeof and valueOf inspection
* 'S' for store-string
* 'S' for store-string (of any object)
* 'P' for print-string
* 'P' for print-string (of any object)


Prefixes:
Prefixes:
Zeile 659: Zeile 974:
** %e, %E, %f, %g always show decimal point
** %e, %E, %f, %g always show decimal point


Conversions (upper case same as lower case, except for xX):
Conversions:
* 'a' (not implemented) hex floating point exp form
* 'a' (not implemented) hex floating point exp form
* 'b' binary (base 2)
* 'b' binary (base 2)
Zeile 666: Zeile 981:
* 'e' base-10 floating point exp form (scientific)
* 'e' base-10 floating point exp form (scientific)
* 'f' base-10 floating point decimal form (non-scientific)
* 'f' base-10 floating point decimal form (non-scientific)
* 'g' 'e' or 'f', whichever looks more appropriate (based on value)
* 'g' 'e' or 'f', whichever looks more appropriate (based on the float-value)
* 'i' integer (alias for 'd')
* 'i' integer (alias for 'd')
* 'j' (not implemented) JSON format
* 'j' (not implemented) use 'J' for JSON format
* 'n' (not implemented) stores number of characters written so far into arg
* 'n' (not implemented) stores number of characters written so far into arg
* 'o' base-8 octal
* 'o' base-8 octal
Zeile 683: Zeile 998:


Dynamic width/precision (consumed in order as presented):
Dynamic width/precision (consumed in order as presented):
* "*" take width/parameter from next argument
* "*" take width/parameter from next argument


Special output specifier:
Examples:
* <n>! if the number's string is larger than the field width <n>, it will be filled with '#'s. Useful if you want to ensure tabular data to remain aligned. This is not a posix printf specified, but a Smalltalk/X extension.

Examples <sup>1)</sup>:
'|%d|' printf: { 123 } -> '|123|'
'|%d|' printf: { 123 } -> '|123|'
'|%5d|' printf: { 123 } -> '| 123|'
'|%5d|' printf: { 123 } -> '| 123|'
Zeile 717: Zeile 1.035:
'|%05d|' printf: { 123 } -> '|00123|'
'|%05d|' printf: { 123 } -> '|00123|'
Field width overflow:
Case of float-format character affects printing of Nan, Infinity and exponent separator:
'|%4d|' printf: { 123456 } -> '|123456|'
'|%4!d|' printf: { 123456 } -> '|####|'


The case (upper vs. lower) of the float-format character affects printing of Nan, Infinity and exponent separator:
'%f' printf: { 1.234 } -> '1.234000'
'%f' printf: { 1.234 } -> '1.234000'
'%F' printf: { 1.234 } -> '1.234000'
'%F' printf: { 1.234 } -> '1.234000'
Zeile 732: Zeile 1.055:
'% F' printf: {Float infinity} -> ' INF'
'% F' printf: {Float infinity} -> ' INF'
'% F' printf: {Float negativeInfinity} -> '-INF'
'% F' printf: {Float negativeInfinity} -> '-INF'

1) Reminder: the "{ ... }" syntax in Smalltalk generates an Array containing the elements (expressions) separated by periods. I.e. "{ 1+2 . 3+4 }" would generate an array with 2 elements: 3 and 7.<br>With constant arguments, this is (almost) equivalent to #( el1 el2) (without periods). Except for the fact, that constant arrays are immutable (readonly), whereas the brace construct instantiates a new array which is mutable.


== Scanf Format Specifier ==
== Scanf Format Specifier ==
Zeile 750: Zeile 1.075:
* 'x' base-16 hex
* 'x' base-16 hex
* 'n' any number
* 'n' any number
* 'J' JSON object (upper case 'J' only)


Length prefix:
Length prefix:
Zeile 768: Zeile 1.094:
('%Lf' sscanf:'1234') first -> 1234.0 (LongFloat i.e. an IEEE extended)
('%Lf' sscanf:'1234') first -> 1234.0 (LongFloat i.e. an IEEE extended)
('%LLf' sscanf:'1234') first -> 1234.0 (QDouble)
('%LLf' sscanf:'1234') first -> 1234.0 (QDouble)

= See Also =

[[Numeric Limits/en|Numeric Limits]] provides additional info on precision, ranges and problems with floating point numbers.

Aktuelle Version vom 5. Juli 2023, 10:14 Uhr

This document lists most useful (and most often needed) functions. Be aware, that there are many more to be found in either the class references or via the builtin class browser.

See also "Numbers" in Expecco_API.
Reference: Integer, Float, Fraction, ScaledDecimal, Complex which all inherit from Number

Back to Useful API Functions

Literals (i.e. Constant Numbers)[Bearbeiten]

Literals are constants as written in elementary Smalltalk code and also given as freeze value to a pin or initial value to a variable.

Integer Literals[Bearbeiten]
1234 
1234567890123456789012345678901234567890
-123456789012345678901234567890
0xaffe or 16rFFAA (hex in C/JSON or Smalltalk syntax)
-0xaffe or 16r-FFAA (negative hex in C- or Smalltalk syntax)
0b101010 or 2r0101 (binary in C/JSON or Smalltalk syntax)
0o377 or 8r377 (octal)
<N>rXXX (arbitrary radix N)

Integer constant; decimal, hex, binary, octal or any base N;
integers may be arbitrary long

Floating Point Literals (Limited Precision Rationals)[Bearbeiten]
0.5
1e5
-1.2e-3
12.6789q or 1.7e-21q (extended precision)
3.6789f or 2.67e5f (single precision)

Float constant; actually IEEE double precision;
use "q" instead of "e" for extra precision (extended IEEE floats) or "f" for single/less precision.

In addition to single, double and extended floats, additional precision representations are available (see below).

Fraction Literals[Bearbeiten]
(4/3)
(523423432/3)
(-5/3)

Fraction constants (numerator / denominator); these are exact

Scaled Decimal Literals[Bearbeiten]
123.456s2
-33.4s2
100s2

Scaled decimal; the number after the "s" defines the print-scale. The above numbers print themself rounded to 2 fractional digits e.g. "123.46", "-33.40" or "100.00" (although internally, the full precision is kept for further operations).

Complex Number Literals[Bearbeiten]
(4+3i) or (-5+2i) or (-10-4i)
(4.3+3.1i) or (4.3 + 1i) 
5.0 i or 5i

Complex number (real part / imaginary part)

Wellknown Constant Numbers[Bearbeiten]

A few common constants are known by name. They are answered by corresponding getter messages sent to the number class of which you want the constant (i.e. these return the constants in their respective precision):

Float pi
pi as IEEE double precision number
FloatD pi
Float64 pi
the same as above (FloatD and Float64 are aliases for the default float class "Float")
FloatQ pi
Float80 pi
pi as IEEE extended precision number (FloatQ and Float80 are aliases for the extended float class also known as "LongFloat")
FloatE pi
Float32 pi
pi as IEEE extended precision number (FloatE and Float32 are aliases for the single precision float class also known as "ShortFloat")
<FloatClass> ln2
<FloatClass> ln10
<FloatClass> sqrt2
<FloatClass> sqrt3
<FloatClass> e
<FloatClass> NaN, infinity and negativeInfinity

Take a look at the class in a class browser for additional useful constants.

Float Representations[Bearbeiten]

Standard Float Representations[Bearbeiten]

For traditional reasons, the name "Float" refers to IEEE double precision floating point numbers in expecco, whereas IEEE single precision floats are called "ShortFloats". For more readability, the float classes can also be referred to via their aliases:

Float32 = FloatE (=ShortFloat),
Float64 = FloatD (=Float)
Float80 = FloatQ (=LongFloat).

There is usually no need to explicitly use or refer to ShortFloats (or FloatEs): modern CPUs usually process them as fast as doubles.
However, you may need them to either simulate single precision arithmetic (which may show different convergence behavior in some series computations) or to exchange binary data with other systems (i.e. to generate a byteArray containing the float's bits or to write a single precision float's bits to a stream).

Float / FloatD / Float64[Bearbeiten]

Floats (double precision IEEE floats) are stored in 64 bits, having an 11-bit exponent and a 52+1 bit mantissa (1 bit is hidden due to normalization).
This gives roughly 15 digits of precision.
This is the default used, if you write a float number in the code.

ShortFloat / FloatE / Float32[Bearbeiten]

ShortFloats (single precision IEEE floats) are stored in 32 bits, having an 8-bit exponent and a 23+1 bit mantissa (1 bit is hidden due to normalization).
This gives roughly 7 digits of precision.

LongFloat / FloatQ / Float80[Bearbeiten]

LongFloats (extended precision IEEE floats) are stored in 80 bits, having a 15-bit exponent and a 64 bit mantissa.
This gives roughly 19 digits of precision.


By Default, Floats print themself with either a decimal point or an exponent indicator 'e', e.g. "0.5", "10.0" or "1.3e3". However, there are a number of functions provided to print numbers in other formats.

Experimental Extra Float Representations[Bearbeiten]

For background information on why you should not trust IEEE floating point arithmetic, and why you may need more precision in some situations, please read the article "Do not trust Floating Point".

Expecco includes experimental versions for higher precision floats. Please do not use them for production code. They are considered being "work in progress", and may or may not work as expected. Especially trigonometric and other math functions are known to be erroneous or generate less precise results as expected. Please use those with extra care and report bugs.

For now, we recommend the use of LargeFloat instead of QuadFloat/OctaFloat or QDouble if large precision is needed.

LargeFloat[Bearbeiten]

LargeFloats use an arbitrary (configurable) number of bits to represent floats with any precision.
They are completely software emulated, which makes most operations much slower than with other floats. In other languages, these are sometimes called "BigFloat".

Usage is similar to QDoubles as described below. However, when creating aLargeFloat, you have to give the desired precision (in bits) as argument:

1.0 asLargeFloatPrecision:200

or in decimals:

1.0 asLargeFloatDecimalPrecision:100

If no precision is given, a default prcision of 200 bits is used, as e.g. by:

1.0 asLargeFloat

You will get roughly 1 decimal digit of precision per 3 bits (i.e. the above 200bit precision corresponds to a decimal precision of roughly 60 digits).

Example (1):

45 degrees sin
    => 0.707106781186547 
       (a float with roughly 15 digits precision)

(45 asLargeFloatPrecision:200) degrees sin
    => 0.70710678118654752440084436210484903928483593768847403658834

and back:
(45 asLargeFloatPrecision:200) degrees sin arcSin radiansToDegrees
   => 45.0

1) the meaning of "degrees" is described in the "Physical Values" document.

QDouble / FloatQD[Bearbeiten]

QDoubles use 4 double precision floats (holding the unevaluated sum of 4 doubles) to represent a float with roughly 200 bits of precision (actually often more, depending on the values).
QDoubles are able to represent sums/differences of a very large float with a very small float.
For example with regular floats (i.e. IEEE double precision):

(1e200 + 1e-15) - 1e200
    => 0.0

the small value is lost.
Whereas with QDoubles as in:

(1e200 asQDouble + 1e-15) - 1e200
    => 1e-15

it is preserved.

QDoubles are thus able to represent sums of wildly distant numbers. With regular floats, the following computations all deliver a wrong result:

1e200 + 1e-15 + 1e-100                              
    => 1E+200  (loosing 1e-15 + 1e-100)

(1e200 + 1e-15 + 1e-100) - 1e200             
    => 0       (wrong; lost 1e-15 + 1e-100)

(1e200 + 1e-15 + 1e-100) - 1e200 - 1e-15
    => -1e-15  (wrong)

(1e200 + 1e-15 + 1e-100) - 1e200 - 1e-100          
    => -1E-100 (wrong)

(1e200 + 1e-15 + 1e-100) - 1e200 - 1e-15 - 1e-100   
    => -1E-015 (wrong)

whereas with QDoubles, we get:

1e200 asQDouble + 1e-15 + 1e-100                              
    => 1E+200  (printed, actual value is correct)

(1e200 asQDouble + 1e-15 + 1e-100) - 1e200                    
    => 1.0e-15 (correct)

(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-15            
    => 1E-100  (correct)

(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-100           
    => 1E-015  (correct)

(1e200 asQDouble + 1e-15 + 1e-100) - 1e200 - 1e-15 - 1e-100   
    => 0.0     (correct)

or another example:

t := 1234 + 0.567890 + 0.00000012345 + 0.000000000006789.
a := t - 1234.              "/ 0.567890123456891     (mhmh ?) 
b := a - 0.567890.          "/ 1.23456891154561E-07  (mhmh ?) 
c := b - 0.00000012345.     "/ 6.89115456081139E-12  (mhmh ?)
d := c - 0.000000000006789. "/ 1.0215456081139E-13   (wrong)

whereas:

t := 1234 asQDouble + 0.567890 + 0.00000012345 + 0.000000000006789.
a := t - 1234.              "/ 0.56789012346    (mhmh ?)
b := a - 0.567890.          "/ 1.23456789e-7    (mhmh ?)
c := b - 0.00000012345.     "/ 6.789E-12        (correct) 
d := c - 0.000000000006789. "/ 0.0              (correct)

However, there is no insurance, that bits are not lost. If one of the operands already needs all four doubles (because it cannot be represented exactly as a sum of 3 floats), bits from the second operand may be lost. For example:

1e100 asQDouble + 1

will result in 1e100 (without the one), because 1e100 already uses all bits (i.e. all 4 doubles) of the QDouble. If you need the full precision, you may have to use LargeFloats, although the processing overhead may be larger then.

Due to the extra processing overhead, operations are slower than with doubles or extended doubles.

Attention:
Strange results seem to be generated when regular floats are converted to QDoubles iff the original float was not representable as an exact number. For example, adding the float 0.2 to the QDouble 1.0QD will result in a number different from 1.2QD, because the original 0.2 had an error in its last bit, which gets now visible when converted to QDouble.

Better use LargeFloat instead, if more precision is needed.

QuadFloat / Float128[Bearbeiten]

QuadFloats use the 128 bit IEEE quadruple precision binary128 format, with 15 exponent bits, providing roughly 34 digits of precision.
QuadFloats are software emulated, and thus computations are slower than with regular floats.

Attention:
Do not use Quadfloats for now, except to convert from/from binary data. Currently, they may not handle subnormals in some arithmetic operations correctly and may also return slightly incorrect results for trigonometric operations (rounding modes are not correctly implemented). Use LargeFloat if more precision is needed.
OctaFloat / Float256[Bearbeiten]

OctaFloats use the 256 bit IEEE octuple binary256 format, with 19 exponent bits, providing roughly 70 digits of precision.
OctaFloats are also software emulated by a flexible arbitrary precision IEEE algorithm, and slower than QuadFloats and QDoubles (actually often even slower than LargeFloats below).

Attention:
Do not use Octafloats for now, except to convert from/from binary data. Currently, they do not handle subnormals in some arithmetic operations correctly and may also return slightly incorrect results for trigonometric operations (rounding modes are not correctly implemented). Use LargeFloat if more precision is needed.

Fractions[Bearbeiten]

Fractions are returned from integer divisions; i.e. when both "a" and "b" are integers and "a / b" does not result in an integral result.
Fractions are exact; no precision is lost. Results of arithmetic operations are reduced and possibly yield integers. Thus:

(1/3) * (1/3)
     => (1/9)

and:

(1/3) * 9
     => 3 (an exact integer)

Fractions print themself as "(a / b)".
They are computed in software and thus usually slower than float operations (especially with huge numerators/denominators).

Scaled Decimals[Bearbeiten]

These print themself rounded to a specified number of fractional digits (the so called scale).
For example, "1234.567 asScaledDecimal:2" will print itself as "1234.57" (i.e. rounded).
However, internally the full precision is kept so an arithmetic operation will still deliver a correct result.

Scaled decimals are perfect to present values to a user or in a report in a "human friendly" rounded format.
Example:

a := 1234.567 asScaledDecimal:2.
a print.  
    => '1234.57'

b := 23.007 asScaledDecimal:2
b print.  
    => '23.01'

(a + b) print.
    => '1257.57'

This is because the sum (a+b) is actually (1234.567 + 23.007 = 1257.574), which is printed as '1257.57' (rounded).


This also works for Fractions:
Fraction example:

c := (1/3) asScaledDecimal:2.
c print.  
    => '0.33'

d := (2/3) asScaledDecimal:2
d print.  
    => '0.67'

(c + d) print.
    => '1.00'

Be aware that the output will look strange (i.e. look wrong) if monetary values are presented this way, e.g. on an invoice's summation. Here, we'd expect a sum of amounts to be the sum of previously listed values (think of sales tax being computed, giving a rounded Cent-value).
See FixedDecimal below for a better solution.

ScaledDecimals can be rounded to their scale, so that further computation are taking that value. Thus taking the above values rounded:

a := a roundedToScale.
b := b roundedToScale.
(a + b) print.
    => '1257.58'

shows the correct value in a table.

You can also use "truncatedToScale", to continue arithmetic with the truncated value.

Fixed Decimals[Bearbeiten]

(new with expecco 21.2)
Similar to ScaledDecimals; however, these do NOT hold the correct result, but instead always round to the specified scale and thus the value used for further operations is the (rounded) value printed.
Arithmetic operations will deliver a rounded result. Fixed decimals are good to represent money, especially when computing and printing sums of monetary values e.g. in an invoice.
Example:

a := 1234.567 asFixedDecimal:2.
a print.  
    => '1234.57'

b := 23.007 asFixedDecimal:2
b print.  
    => '23.01'

(a + b) print.
    => '1257.58'

This looks correct to a human, as the values sum up correctly.

Be aware that converting a float to a FixedDecimal and back will not necessarily return the starting number. Unlike ScaledDecimals, FixedDecimals do NOT preserve the original value.

If you have a pre 21.2 version, the FixedDecimal behavior can be "simulated" by forcing a ScaledDecimal to round its value to the shown scale (as described above).

Number Ranges[Bearbeiten]

These behave like collections (see there) and are typically created by one of the following:

(start to: stop)
(start to: stop by: step)

For example:

(1 to:10) do:[:i |
  Transcript showCR: e'{i} squared is {i squared}'.
]

Complex Numbers[Bearbeiten]

Are created as constants "(a + b i)" or created with "Complex real:a imaginary:b".
An imaginary is created with the "i" message (e.g. "5 i" yields (0 + 5 i).
Complex numbers print themself as "(a + b i)".

Complex results can also be returned from e.g. the square root operator (sqrt) and logarithm operations (log, ln) IFF imaginary results are trapped (which means that an exception handler for the ImaginaryResult notification is present and proceeds the exception).
The convenient helper "trapImaginary:" does that for you:

-4 sqrt

will report an error, whereas:

Number trapImaginary:[ -4 sqrt ]

will return a complex result.

If imaginary results are not trapped, square root and log operators will signal an exception instead.

Measurement Values[Bearbeiten]

These hold an error percentage in addition to the actual value. These are useful to track upper and lower bounds of a measured or estimated value. Arithmetic operations will keep this error in the result.
They can be constructed from any number via the "±" or "±%" binary operators:

(aNumber ± errRange)
a measurement value with ± an absolute error of errRange.
(aNumber ±% percentage)
a measurement value with a relative error of percentage.

For example,
"(50 ± 3)" represents a measurement value with 6% accuracy (i.e. the actual value is somewhere in the interval [50-3 .. 50+3]), and
"(100 ±% 3)" represents a measurement value with 3% accuracy (i.e. the value is in [100-3 .. 100+3]).

Measurement values are not real numbers, but can in most operations be treated like one (i.e. the usual arithmetic operations are supported).

Physical Values[Bearbeiten]

These hold a number or measurement value in addition to a unit (e.g. meter, kilogram, volt, ampere, etc.). They are documented in depth in a separate part of this wiki. Physical values are created via unit operators.
For example, "50 volt" represents a voltage value of 50 volts.
Physical values are not numbers, but can in most parts be treated like one (i.e. most arithmetic operations are supported).

100 volt * 3

yields "300 V". And:

100 volt * 0.1 ampere

yields "10 W" (watt). And:

10 volt / 2 ampere

yields "5 ohm".

Physical values can also be combined with measurement values:

100 volt ±% 3

represents a measured voltage with 3% possible error (i.e. "(100 ± 3) V").
And:

10 volt ± 2 volt

represents a measured voltage with 20% error (i.e. value in [8 .. 12] V")

See details in the "Physical Values" document.

Operations with Mixed Types[Bearbeiten]

Normally, there is no need for explicit conversion between number types. The result of mixed operations is computed with the type of the operand which has the higher "generality". This conversion is called "coercion" - i.e. the operand with the lower generality is coerced into the type of the other before the operation is performed.

The order of generalities is:

Integer < Fraction < ScaledDecimal < FixedDecimal 
   < Float32 < Float64 < Float80 < Float128 < Float256 < LargeFloat < Complex

Thus, when a calculation involves both an integer and a fraction, the result will be a fraction (unless the result can be reduced to an integer).
When an operation involves a float and an integer or fraction, the result will be a float.
When either one is a complex, the result will also be.

When two floats are involved, the result will be generated with the higher precision.

But you should not be fooled by that: we do not get previously lost bits back, when a lower precision float is converted to a higher precision; the missing bits are simply assumed to be zero. In other words: "ShortFloat pi asFloat" will still only have roughly 7 digits of precision (which the original short float had), whereas "Float pi" will have its 15 digits.

Mixed Operations with MeasurementValues[Bearbeiten]

Automatic conversion is also performed when MeasurementValues are involved:

aMeasurementValue + aNumber => MeasurementValue
aMeasurementValue - aNumber => MeasurementValue
the result will have the same error as the receiver.
E.g. (10 ± 1) + 10 => (20 ± 1).

 

aMeasurementValue * aNumber => MeasurementValue
aMeasurementValue / aNumber => MeasurementValue
the error will also be scaled by aNumber.
E.g. (10 ± 1) * 10 => (100 ± 10).

 

Mixed Operations with PhysicalValues[Bearbeiten]

PhysicalValues can be scaled by a scalar or multiplied by another physical value (possibly resulting in a value with a different unit). Addition and subtraction are only allowed if the arguments have the same base type:

aPhysicalValue + aNumber => error
aPhysicalValue - aNumber => error
not allowed

 

aPhysicalValue * aNumber => PhysicalValue
aPhysicalValue / aNumber => PhysicalValue
for example, 10 volt * 10 => 100 volt,
and 10 volt / 1000 => 10 milliVolt

 

Most Common/Useful Operations[Bearbeiten]

Testing[Bearbeiten]

aNumber isNaN => Boolean
aNumber.isNaN() (in JS syntax)
Check if number is NaN ("Not a Number"). Notice that there are multiple representations of "NaN": "Float32 NaN", "Float64 NaN" etc.
Therefore, you should not compare against NaN with an identity compare operations (i.e. you should use isNaN to test, not compare for identity against another NaN)

 

aNumber isFinite => Boolean
Check if number is not infinity and not NaN. As with NaN, there are multiple such "infinities"; one in each float class.

 

aNumber isInfinite => Boolean
Check if number is either positive infinity (INF) or negative infinity (-INF).

 

aNumber isPositiveInfinity => Boolean
Check if number is the positive infinity (+INF).

 

aNumber isNegativeInfinity => Boolean
Check if number is the negative infinity (-INF).

 

aNumber isInteger => Boolean
Check if number is an integral number.

 

aNumber isFraction => Boolean
Check if number is a fractional number.

 

aNumber isFloat => Boolean
Check if number is any float number (Float32, Float64, Float128, etc.).

 

aNumber exponent => Integer
For floats only: returns the exponent, such that the number's value is:
"mantissa * (2 ^ exponent)".

 

aNumber mantissa => Integer
For floats only: returns the mantissa, such that the number's value is:
"mantissa * (2 ^ exponent)".

 

aNumber precision => Integer
For floats only: returns the number of bits in the number's mantissa.

 

aNumber decimalPrecision => Integer
For floats only: returns the number of digits in the number's mantissa.

 

floatClass fmin => float
For float classes only: returns the smallest representable (normalized) number of that class.
For example, "FloatD fmin" would return 2.2250738585072e-308. Any operation which would generate a smaller number will deliver -INF.

 

floatClass fmax => float
For float classes only: returns the largest representable number of that class.
For example, "FloatD fmax" would return 1.79769313486232e+308. Any operation which would generate a larger number will deliver +INF.

 

floatClass emin / emax => integer
For float classes only: returns the smallest and largest possible exponent representable by numbers of that class.
For example, "FloatD emin" would return -1022. Notice that this is the exponent of the power-of-two; the corresponding decimal min/max exponent can be computed by multiplying it by log10(2).

 

aNumber isComplex => Boolean
Check if number is a complex number.

 

aNumber negative => Boolean
same as aNumber < 0

 

aNumber positive => Boolean
same as aNumber >= 0

 

aNumber strictlyPositive => Boolean
same as aNumber > 0

 

anInteger isPrime => Boolean
true if the number is a prime number

 

anInteger isPowerOf2 => Boolean
true if there exists an n, such that 2ˆn equals the number

 

anInteger isPowerOf: b => Boolean
true if there exists an n, such that bˆn equals the number

 

Arithmetic[Bearbeiten]

aNumber + aNumber => Number
aNumber - aNumber => Number
aNumber * aNumber => Number
aNumber / aNumber => Number
The usual arithmetic operators.
All of the above allow operands of any number type, and will generate a result as appropriate. When dividing integers, an exact result is returned (either integer or fraction). If any of the arguments is inexact (i.e. a floating point number), the result will be inexact. If both are exact, the result will be exact. Fractional results are reduced to the greatest common divisor as denominator.
Point right.png Notice, that Smalltalk evaluates them left to right, without special precedences.
Thus you should always use parentheses to group expressions when there are two or more operators in an arithmetic expression. It is good practice to use parentheses even in expressions where the evaluation order gives the correct result.

 

aNumber ** aNumber => Number
aNumber raisedTo: aNumber => Number
exponentiation (raising to a power)
Examples:
 2 ** 20
     => 1048576
 4 ** 3.5
     => 128.0
 100 ** 0.5
     => 10.0

 

aNumber // aNumber => Integer
aNumber \\ aNumber => Integer
Truncated result and remainder (towards the next smaller integer i.e. towards negative infinity).
The following equation holds: (a // b) * b + (a \\ b) = a
Examples:
 100 // 3
     => 33
 100 \\ 3
     => 1
 -100 // 3
     => -34
 -100 \\ 3
     => 2

 

aNumber quo: aNumber => Integer
aNumber rem: aNumber => Integer
Truncated result (towards zero) and corresponding remainder.
For positive arguments, this is the same as the above, for negative args, a different result is returned.
However, the equation is similar to above: (a quo: b) * b + (a rem: b) = a
Examples:
 100 quo: 3
     => 33
 100 rem: 3
     => 1
 -100 quo: 3
     => -33
 -100 rem: 3
     => -1

 

aNumber abs => Number
the absolute value.
aNumber negated => Number
the negated value.

Mathematical and Trigonometric Functions[Bearbeiten]

The usual operations are provided as unary messages to the number:

aNumber ln => Number
aNumber log10 => Number
aNumber log2 => Number
aNumber log: base => Number
aNumber integerLog10 => Integer
aNumber integerLog2 => Integer
logarithm (natural, base10, base2 or arbitrary base).
These are not restricted to floats; they can also be applied to big integers,
as in: "1000 factorial ln".
By default, an error is reported for negative numbers;
to get a complex result, use "Complex trapImaginary:[ aNumber ln ]".

 

aNumber sqrt => Number
anInteger integerSqrt => Integer
square root and truncated square root
By default, an error is reported for negative numbers;
to get a complex result, use "Complex trapImaginary:[ aNumber sqrt ]".

 

aNumber cbrt => Number
anInteger integerCbrt => Integer
cubic root and truncated cubic root.

 

aNumber nthRoot: n => Number
the nth root.
"n nthRoot:2" gives the same result as "sqrt"
and "n nthRoot:3" the same as the cubic root.

 

aNumber exp => Number
number1 raisedTo: number2 => Number
number1 ** number2 => Number
exponentiation; the "**" binary operator is an alias for "raisedTo:".

 

aNumber sin => Number
aNumber cos => Number
aNumber tan => Number
aNumber cot => Number (cotangent)
aNumber sec => Number (secant)
aNumber csc => Number (cosecant)
aNumber arcSin => Number
aNumber arcCos => Number
aNumber arcTan => Number
aNumber arcTan2: x => Number
trigonometric functions

 

aNumber sinh => Number
aNumber cosh => Number
aNumber tanh => Number
aNumber arSinh => Number
aNumber arCosh => Number
aNumber arTanh => Number
hyperbolic functions

Truncation and Rounding[Bearbeiten]

aNumber ceiling => Number
returns the next larger integer (unless aNumber is integral).
E.g. truncates towards positive infinity.
aNumber floor => Number
returns the next smaller integer (unless aNumber is integral).
E.g. truncates towards negative infinity.
aNumber truncated => Integer
truncates towards zero
aNumber truncateTo: grid => Number
truncates towards the nearest multiple of grid.
E.g. "1.284 truncateTo:0.1" yields "1.2".
aNumber rounded => Number
rounds up/down towards the nearest integer
aNumber roundTo: grid => Number
rounds up/down towards the nearest multiple of grid.
E.g. "1.284 roundTo:0.1" yields "1.3" and "523 roundTo:5" yields "525".
aNumber roundToNumberOfDigits: n => Number
rounds up/down for n valid digits.
E.g. "1.284 roundToNumberOfDigits:2" yields "1.3" and "5234 roundToNumberOfDigits:2" yields "5200".
aNumber roundToPrecision: n => Number
rounds up/down for n decimal fraction digits.
E.g. "1.284 roundToPrecision:2" yields "1.28" and "5234.356 roundToPrecision:2" yields "5234.36".

Statistical / Combinatorical Functions[Bearbeiten]

anInteger factorial => Integer
the factorial; i.e. "n factorial" is 2*3*4...*n". Huge numbers are to be expected (try "1000 factorial inspect" in a workspace).
n binomialCoefficient: k => Integer
n binco: k => Integer
the binomial coefficient (aka. n over k or the number of ways of picking k unordered outcomes from n possibilities)
n agm: y => Float
the arithmetic-geometric mean

Other Special Functions[Bearbeiten]

integer1 gcd: integer2 => Integer
the greatest common divisor of integer1 and integer2.
integer1 lcm: integer2 => Integer
the least common multiple of integer1 and integer2.
anInteger fib => Integer
the nth Fibonacci number. Huge numbers are to be expected (try "1000 fib inspect" in a workspace).
aNumber fib_binet => Float
an approximation of the nth Fibonacci number according to Binet.
For example, "5000 fib_binet" gives: "1.0777734893072974780...e+10449" (by default with 200 bits precision)
aNumber erf => Float
the error function
aNumber gamma => Float
the gamma function
anInteger nextPrime => Integer
the next prime number.
anInteger primeFactors => Collection
the prime factors. Can take a long time for big numbers.

Bitwise Operators[Bearbeiten]

integer1 bitAnd: integer2 => Integer
integer1 bitOr: integer2 => Integer
integer1 bitXor: integer2 => Integer
bitwise and, or and exclusive or
integer1 bitShift: count => Integer
left shift if count is positive; right shift if negative
integer1 leftShift: count => Integer
left shift by count
integer1 rightShift: count => Integer
right shift by count
integer1 bitTest: integer2 => Boolean
integer2 is used as a mask (i.e. bitTest returns true if any bit in the mask is set in the left operand i.e. (i1 & i2) not equal 0
integer1 bitAt: bitNr => integer (0 or 1)
extract the nth bit, with bitNr starting at 1
integer1 lowBits: count => integer
extract count lowest bits
integer highBit => integer (1..)
the bit number of the highest bit, with bitNr starting at 1; zero if no bit is set
integer lowBit => integer (1..)
the bit number of the lowest bit, with bitNr starting at 1; zero if no bit is set

Printing[Bearbeiten]

Numbers can print themself on an output stream, or convert themself to a string:

aNumber printOn: aStream => void
aNumber printOn: aStream radix: base => void
aNumber printOn: aStream leftPaddedTo: length => void
aNumber printOn: aStream leftPaddedTo: length with: padCharacter => void
aNumber printOn: aStream paddedTo: length => void
aNumber printOn: aStream paddedTo: length with: padCharacter => void
aNumber printString => String
aNumber printStringRadix: base => String
aNumber printStringLeftPaddedTo: length => String
aNumber printStringLeftPaddedTo: length with: padCharacter => String
aNumber printStringPaddedTo: length => String
aNumber printStringPaddedTo: length with: padCharacter => String
The above generate a standard format, which should fit most needs. The padded variants fill with either space or the explicit padCharacter. The printOn: variants will send the string to an output stream; the printString variants will return the string.

 

formatString printf: { arg... } on: aStream => void
formatString printf: { arg... } => String
More fine control is available via the printf functions, which also offer a range of options to fill left or right, to control printing of the sign and to fill with zeros.
These two interpret the receiver as a C-printf-style format string, and an argument vector as first argument (use a brace-array constructor or pass a collection as argument).
Thus, multiple values are printed as in the following example:
'%04x %3d %+4.3f\n' printf:{ 123 . 4 . 3.14159 } on:Transcript
Individual conversions (to a string) can also be done with:
aNumber printfPrintString: formatString => String
Examples:
'% .4f' printf:{Float pi}         => ' 3.1416' (space after % ensures space for sign)
'% .4f' printf:{Float pi negated} => '-3.1416' (space after % ensures space for sign)
'%+.4f' printf:{Float pi}         => '+3.1416' ('+' after % enforces sign)
'%+.4f' printf:{Float pi negated} => '-3.1416' ('+' after % enforces sign)
Please refer to a C-printf manual page (e.g. https://en.wikipedia.org/wiki/Printf_format_string).
Notice that printf accepts C-style character escapes (which is not the case in general with Smalltalk string constants)

 

aNumber printRomanOn: aStream => void
roman style

Reading from Streams / Converting from Strings[Bearbeiten]

Numbers can be read from a stream or converted from a string. There are slight differences between them:

  • when reading from a stream of characters, the stream will be positioned after the number. So any non-digit character(s) after the number's characters will be returned by future read operations. The stream can be an internal or external (i.e. file-, pipe- or socket-) stream.
  • when converting from a string, no extra characters are expected/allowed after the number's digits, except for whitespace. Thus you'll usually get an error when trying to convert a string with garbage characters after the number (which is not the case when reading from a stream).

Therefore, if you want to read a number from a string which may have garbage characters after the digits, you should first create a read-stream on the string, and then read the number from the stream (i.e. use "Number readFrom:(someString readStream)" instead of "Number fromString:someString").

Numbers are read by sending the Number-class or one of its subclasses one of the "readFrom:" or "fromString:" messages.

If the class is the abstract class Number, then the read code will itself figure out, what kind of number to return. If the class is a concrete class (Float, Integer, Fraction etc.), you will get an instance of that class, unless the characters do not represent a valid number (of that class). In that case, an error is reported.

By default, errors are reported by raising an exception, unless you provide an error-handler as argument to the reader; more on that below.

Number readFrom: aStream => someNumber or error
this can return an instance of any of the number types
Number readFrom: aStream onError:[ errorValue ] => someNumber or errorValue
errorValue can be a constant, an arbitrary Smalltalk expression or even show a warn dialog or do whatever you like. In case of an error, the value returned from the read method will be the value provided by the error-block. Notice, that numbers themself respond to the value message and will return themself. Thus you can also provide a replacement value instead of an error block.
Number fromString: aString => someNumber or error
Number fromString: aString onError:[ errorValue ] => someNumber or fallBackValue
similar, but does not allow for garbage characters after the number (except spaces)
Integer readFrom: aStream
Integer readFrom: aStream onError:[...]
Float readFrom: aStream
Float readFrom: aStream onError:[...]
Integer fromString: aStream
Integer fromString: aStream onError:[...]
Float fromString: aStream
Float fromString: aStream onError:[...]
similar to the above, but these will return a correspondingly typed number (i.e. an instance of Integer, Float, etc.
formatString sscanf: aString => collection
formatString is a printf/scanf-like format string; reads items from aString and returns a collection (i.e. an Array) of scanned objects.
For example,
'%d %x %f' sscanf: '1234 FF 3.1415'
will return an array-like collection with 3 elements, the integer 1234, the integer 255 and the float 3.14159.
formatString scanf: aStream => collection
like above, but the elements will be read from a character stream
To read binary numbers, refer to the stream API.

Conversion[Bearbeiten]

In certain situations, it may be desirable to convert explicitly to a particular type, for example when binary data has to be verified or filled into a byte-buffer.

aNumber asInteger => Integer
truncates to an integer (i.e. same as "truncated")
aNumber asFloat => Float64
aNumber asFloat64 => Float64
aNumber asFloatD => Float64
generates a double precision float; may generate +/- INF if the value cannot be represented as a double IEEE float (i.e. is out of range). asFloat64 and asFloatD are aliases for compatibility.
aNumber asFloatChecked => Float64 or error
same as above, but reports an error if the value cannot be represented (instead of returning INF).
aNumber asShortFloat => Float32
aNumber asFloat32 => Float32
aNumber asFloatE => Float32
generates a single precision float; may generate +/- INF if the value cannot be represented as a single IEEE float. asFloat32 and asFloatE are aliases.
aNumber asShortFloatChecked => Float32 or error
same as above, but reports an error if the value cannot be represented (instead of returning INF).
aNumber asLongFloat => Float80
aNumber asFloatQ => Float80
generates an extended precision float; may generate +/- INF if the value cannot be represented as an extended IEEE float.
aNumber asLongFloatChecked => Float80 or error
same as above, but reports an error if the value cannot be represented (instead of returning INF).
aNumber asQDouble => QDouble
generates a qDouble
aNumber asQuadFloat => QuadFloat
aNumber asFloat128 => QuadFloat
generates a quadruple precision float (float128)
aNumber asOctaFloat => OctaFloat
aNumber asFloat256 => QuadFloat
generates an octuple precision float (float256)
aNumber asLargeFloatPrecision: numBits => LargeFloat
generates an large float with numBits precision
aNumber asLargeFloatDecimalPrecision: numDigits => LargeFloat
generates an large float with numDigits precision
aNumber asLargeFloat => LargeFloat
generates an large float with the same precision as aNumber
aNumber asFraction => Fraction
generates a fraction (from a float)
aNumber asScaledDecimal: scale => ScaledDecimal
generates a scaled decimal which presents scale fractional digits
aNumber asFixedDecimal: scale => FixedDecimal
generates a fixed decimal which rounds on and presents scale fractional digits
aNumber asComplex => Complex
generates a complex (with 0 as imaginary part, same as "nr + 0i")
aNumber i => Complex (that is a lower case i)
generates a complex (with 0 as real part, e.g. as in "0 + nr i")

Examples[Bearbeiten]

Square root of 2 with different precision[Bearbeiten]

nr := 2.0 sqrt.
'%.15g' printf:{nr}   
    => '1.4142135623731'
'%.30g' printf:{nr}   
    => '1.414213562373095101065700873732'
'%.50g' printf:{nr}   
    => '1.41421356237309510106570087373256683349609375'

Be reminded that these floats (which are IEEE doubles) only provide 15 digits of accuracy ("Float decimalPrecision" returns 15). Thus the above attempts to generate more digits are useless and excess digits are more or less random.

More valid digits are returned by QDoubles ("QDouble decimalPrecision" returns 61):

nr := 2.0 asQDouble sqrt.
'%.30g' printf:{nr}   
    => '1.41421356237309504880168872421'
'%.50g' printf:{nr}   
    => '1.4142135623730950488016887242096980785696718753769'
'%.100g' printf:{nr}   
    => '1.414213562373095048801688724209698078569671875376948073176679737988424424484343089516915416653038211'

Here again, digits after the 60th are wrong.

With octuple precision floats ("OctaFloat decimalPrecision" returns 71) we get:

nr := 2.0 asOctaFloat sqrt.
'%.30g' printf:{nr}   
    => '1.41421356237309504880168872421' (a quadruple precision float)
'%.50g' printf:{nr}   
    => '1.4142135623730950488016887242096980785696718753769'
'%.100g' printf:{nr}   
    => '1.41421356237309504880168872420969807856967187537694807317667973799073247801160833747418698891953623'

Finally, an arbitrary number of digits can be computed with LargeFloats (here we use a precision of 1000 bits for roughly 300 digits):

nr := (2.0 asLargeFloatPrecision:1000) sqrt.
'%.30g' printf:{nr}   
    => '1.41421356237309504880168872421'
'%.50g' printf:{nr}   
    => '1.4142135623730950488016887242096980785696718753769'
'%.100g' printf:{nr}   
    => '1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641573'

In most situations, double precision is sufficient. However, some computations generate intermediate results which are outside the precision or range of IEEE doubles. See "Do not trust Floating Point" for a classic (surprising) example.


Reading Numbers[Bearbeiten]

readFrom: will not accept garbage characters after the number iff the argument is a string:

in := '123.456abc'.
Number readFrom: in.
    => error due to garbage after number ('abc')

However, it behaves different, if the argument is a stream.
Then the stream will be left positioned after the number's string:

Number readFrom: (in readstream).
    => 123.456
    (stream will be left positioned at the 'abc')

here, reading the rest after the number's digits:

s := in readstream.
val := Number readFrom: s.
rest := s upToEnd.
    => val: 123.456
       rest: 'abc'

you can provide an error-value:

val := Number readFrom:'bla' onError:[0]
    => val: 0

or perform any action inside the onError arg block:

val := Number readFrom:'blabla' onError:[ Dialog warn:'bad input'. nil ]
    => (Dialog shown)
       val: nil

an alternative to "readFrom:" is scanf, which can also read multiple values from a stream:

row := '%d %f %s' scanf:(ReadStream on:'1234 1111.2345 Fritz').
    => OrderedCollection(1234 1111.2345 'Fritz')
       i.e. an integer, a float and a string

or from a string:

myString := '1234 1111.2345 Fritz'.
row := '%d %f %s' scanf: myString.
    => OrderedCollection(1234 1111.2345 'Fritz')
       i.e. same as above

scanf can also be used to extract numbers which are not delimited by spaces (you have to specify the field length in the format):

myString := '1.234.5679875679'.
'%4f %5f %3d %4d' scanf:myString
    => OrderedCollection(1.23 4.567 987 5679)

Printf Format Specifier[Bearbeiten]

Characters not escaped by a '%' are printed as-is. Following a '%' there can be:

  • optional: '-' (POSIX refers to this as the <<flags>>)
  • optional: positive number or '*' (POSIX: <<width>>)
  • optional: period followed by positive number or * (POSIX: <<precision>>)
  • optional: an h or l to indicate size of data (POSIX: <<length>>)
  • required: character describing output behavior (POSIX: <<conversion specifier>>)

The format follows the official C-library printf formats; however, there are differences in the various printf implementations:

ANSI standards up through C99:

  • more flags: '+' ' ' '0' '#'
  • more lengths: 'L' 'hh' 'll' 'j' 'z' 't'
  • more conversions: 'F' 'a' 'A' 'n'

The POSIX specification of printf added:

  • positional parameters to identify argument indices
  • more flags: (single quote)
  • more conversions: 'C' 'S'
  • clarifications regarding corner cases and 'undefined behavior'

BSD implementations added:

  • more lengths: 'q'
  • more conversions: 'D' 'U' 'O'

glibc (GNU) added:

  • more lengths: 'Z'
  • more conversions: 'm'

Windows C Runtime (CRT) added:

  • more lengths: 'I' 'I32' 'I64' 'w'

glibc and CRT both added length 'Z'.

  • glibc uses 'Z' for the length size_t.
  • CRT uses Z as a conversion for length-prefixed strings.

The expecco/Smalltalk implementation handles 'Z' in the same way as 'z'.

BSD and IBM C library both added 'D'.

  • BSD uses D as a conversion, namely as an alias of 'ld'.
  • IBM uses 'D' for the length for _Decimal64, a decimal floating point type,
  • in accordance with ISO/IEC TR 24732.

The Smalltalk implementation takes the former approach.

The expecco/Smalltalkimplementation also adds new conversions:

  • 'b' and 'B' for binary (base-2) integer renderings
  • 'y' and 'Y' for true/false and yes/no Boolean conversions
  • 'J' for JSON (assuming that the object can be JSON-encoded)
  • 'T' and 'V' for JS typeof and valueOf inspection
  • 'S' for store-string (of any object)
  • 'P' for print-string (of any object)

Prefixes:

  • ' ' fill with spaces
  • '0' fill with zeros
  • '+' print the sign
  • '-' left justified
  • '#' depends:
    • %o, %x, %b: print base prefix
    • %e always show decimal point
    • %e, %E, %f, %g always show decimal point

Conversions:

  • 'a' (not implemented) hex floating point exp form
  • 'b' binary (base 2)
  • 'c' character or (first char of string)
  • 'd' integer
  • 'e' base-10 floating point exp form (scientific)
  • 'f' base-10 floating point decimal form (non-scientific)
  • 'g' 'e' or 'f', whichever looks more appropriate (based on the float-value)
  • 'i' integer (alias for 'd')
  • 'j' (not implemented) use 'J' for JSON format
  • 'n' (not implemented) stores number of characters written so far into arg
  • 'o' base-8 octal
  • 'p' (not implemented) pointer
  • 's' string
  • 't' type (i.e. class name)
  • 'u' (not implemented) unsigned (negative values are converted)
  • 'v' (not implemented) store string
  • 'x' base-16 hex
  • 'X' base-16 hex upper case

Parameter selection (not implemented):

  • <n>$ take n'th parameter

Dynamic width/precision (consumed in order as presented):

  • "*" take width/parameter from next argument

Special output specifier:

  • <n>! if the number's string is larger than the field width <n>, it will be filled with '#'s. Useful if you want to ensure tabular data to remain aligned. This is not a posix printf specified, but a Smalltalk/X extension.

Examples 1):

'|%d|'   printf: { 123 }         -> '|123|'
'|%5d|'  printf: { 123 }         -> '|  123|'
'|%-5d|' printf: { 123 }         -> '|123  |'

'|%s|'  printf: { 'abc' }        -> '|abc|'
'|%5s|' printf: { 'abc' }        -> '|  abc|'
'|%*s|' printf: { 5 . 'abc' }    -> '|  abc|'

'|%f|'    printf: { 1.234 }       -> '|1.234|'
'|%#f|'   printf: { 1.234 }       -> '|1.234000|'
'|%8f|' printf: { 1.234 }        -> '|   1.234|'
'|%*f|' printf: { 8 . 1.234 }    -> '|   1.234|'
'|%10f|'  printf: { 1.234 }       -> '     1.234'
'|%#10f|' printf: { 1.234 }       -> '  1.234000'

Negative width will fill at the right:

'|%5s|'  printf: { 'abc' }       -> '|  abc|'
'|%-5s|' printf: { 'abc' }       -> '|abc  |'
'|%-*s|' printf: { 5 . 'abc' }   -> '|abc  |'
'|%*s|'  printf: { -5 . 'abc' }  -> '|abc  |'

'|%-8f|' printf: { 1.234 }       -> '|1.234   |'
'|%*f|'  printf: { -8 . 1.234 }  -> '|1.234   |'
'|%-*f|' printf: { 8 . 1.234 }   -> '|1.234   |'
'|%-*f|' printf: { -8 . 1.234 }  -> '|1.234   |'

A Zero as fill character (only at the left):

'|%05s|'  printf: { 'abc' }      -> '|00abc|'
'|%05d|'  printf: { 123 }        -> '|00123|'

Field width overflow:

'|%4d|' printf: { 123456 }       -> '|123456|'
'|%4!d|' printf: { 123456 }      -> '|####|'


The case (upper vs. lower) of the float-format character affects printing of Nan, Infinity and exponent separator:

'%f' printf: { 1.234 }                 -> '1.234000'
'%F' printf: { 1.234 }                 -> '1.234000'
'%e' printf: { 1.234 }                 -> '1.234e0'
'%E' printf: { 1.234 }                 -> '1.234E0'
'%f' printf: {Float NaN}               -> 'nan'
'%F' printf: {Float NaN}               -> 'NAN'
'%f' printf: {Float infinity}          -> 'inf'
'%F' printf: {Float infinity}          -> 'INF'
'%f' printf: {Float negativeInfinity}  -> '-inf'   
'%F' printf: {Float negativeInfinity}  -> '-INF'
'%-F' printf: {Float infinity}         -> '+INF'
'%-F' printf: {Float negativeInfinity} -> '-INF'
'% F' printf: {Float infinity}         -> ' INF'
'% F' printf: {Float negativeInfinity} -> '-INF'

1) Reminder: the "{ ... }" syntax in Smalltalk generates an Array containing the elements (expressions) separated by periods. I.e. "{ 1+2 . 3+4 }" would generate an array with 2 elements: 3 and 7.
With constant arguments, this is (almost) equivalent to #( el1 el2) (without periods). Except for the fact, that constant arrays are immutable (readonly), whereas the brace construct instantiates a new array which is mutable.

Scanf Format Specifier[Bearbeiten]

The Smalltalk implementation adds new conversions:

Conversions (upper case same as lower case):

  • 'b' binary (base 2)
  • 'c' character or (first char of string)
  • 'd' decimal
  • 'e' float
  • 'f' float
  • 'g' float
  • 'i' integer (alias for 'd')
  • 'o' base-8 octal
  • 's' string
  • 'u' integer
  • 'x' base-16 hex
  • 'n' any number
  • 'J' JSON object (upper case 'J' only)

Length prefix:

  • 'h' with float formats: reads as ShortFloat
  • 'L' with float formats: reads as LongFloat

Examples:

'%d %x' sscanf:'1234 ff00'         -> OrderedCollection(1234 65280)
'%d %s' sscanf:'1234 ff00'         -> OrderedCollection(1234 'ff00')
'%d %x %b' sscanf:'1234 ff00 1001' -> OrderedCollection(1234 65280 9)
('%f' sscanf:'1234') first         -> 1234.0 (Float i.e. an IEEE double)
('%lf' sscanf:'1234') first        -> 1234.0 (Float i.e. an IEEE double)
('%llf' sscanf:'1234') first       -> 1234.0 (Float i.e. an IEEE double)
('%hf' sscanf:'1234') first        -> 1234.0 (ShortFloat i.e. an IEEE single)
('%Lf' sscanf:'1234') first        -> 1234.0 (LongFloat i.e. an IEEE extended)
('%LLf' sscanf:'1234') first       -> 1234.0 (QDouble)

See Also[Bearbeiten]

Numeric Limits provides additional info on precision, ranges and problems with floating point numbers.



Copyright © 2014-2024 eXept Software AG