Number API Functions: Unterschied zwischen den Versionen
Cg (Diskussion | Beiträge) |
Cg (Diskussion | Beiträge) |
||
(249 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 ===== |
||
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><''N''>rXXX |
|||
0b101010 or 2r0101 <small>(binary in C/JSON or Smalltalk syntax)</small> |
|||
<br>1234567890123456789012345678901234567890 |
|||
0o377 or 8r377 <small>(octal)</small> |
|||
<br>-123456789012345678901234567890</code> |
|||
<''N''>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) ===== |
||
0.5 |
|||
1e5 |
|||
-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 ===== |
||
(4/3) |
|||
(523423432/3) |
|||
(-5/3) |
|||
:: fraction constants (numerator / denominator); these are exact |
|||
Fraction constants (numerator / denominator); these are exact |
|||
===== Scaled Decimal Literals ===== |
===== Scaled Decimal Literals ===== |
||
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) |
|||
(4.3+3.1i) or (4.3 + 1i) |
|||
5.0 i or 5i |
|||
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 |
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 |
::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. |
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 |
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 |
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 |
(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: |
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 |
<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' |
|||
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 |
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 |
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 |
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 |
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 ( |
<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 |
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: |
||
:'''('''''aNumber'' '''±''' ''errRange''''')''' |
|||
: a measurement value with ± an absolute error of ''errRange''. |
:: a measurement value with ± an absolute error of ''errRange''. |
||
:'''('''''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]); |
|||
<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 |
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 ( |
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 |
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). |
|||
|
|||
:''aMeasurementValue'' '''*''' ''aNumber'' => MeasurementValue |
|||
:''aMeasurementValue'' '''/''' ''aNumber'' => MeasurementValue |
|||
::the error will also be scaled by ''aNumber''. |
|||
::E.g. (10 ± 1) * 10 => (100 ± 10). |
|||
|
|
||
==== PhysicalValues ==== |
==== Mixed Operations with PhysicalValues ==== |
||
PhysicalValues can |
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'' |
:''aPhysicalValue'' '''+''' ''aNumber'' => error |
||
:''aPhysicalValue'' '''-''' ''aNumber'' => error |
|||
::not allowed |
::not allowed |
||
|
|||
''aPhysicalValue'' |
:''aPhysicalValue'' '''*''' ''aNumber'' => PhysicalValue |
||
:''aPhysicalValue'' '''/''' ''aNumber'' => PhysicalValue |
|||
::for example, |
::for example, <CODE>10 volt * 10</CODE> => <CODE>100 volt</CODE>, |
||
::and <CODE>10 volt / 1000</CODE> => 10 milliVolt</CODE> |
|||
|
|
||
Zeile 258: | Zeile 391: | ||
=== Testing === |
=== Testing === |
||
''aNumber'' |
:''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) |
|||
|
|
||
''aNumber'' |
:''aNumber'' '''isFinite''' => Boolean |
||
::Check if number is |
::Check if number is not infinity and not NaN. As with NaN, there are multiple such "infinities"; one in each float class. |
||
|
|
||
''aNumber'' |
:''aNumber'' '''isInfinite''' => Boolean |
||
::Check if number is |
::Check if number is either positive infinity (INF) or negative infinity (-INF). |
||
|
|
||
''aNumber'' |
:''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. |
::Check if number is an integral number. |
||
|
|
||
''aNumber'' |
:''aNumber'' '''isFraction''' => Boolean |
||
::Check if number is a fractional number. |
::Check if number is a fractional number. |
||
|
|
||
''aNumber'' |
:''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:<br> "mantissa * (2 ^ exponent)". |
|||
|
|||
:''aNumber'' '''mantissa''' => Integer |
|||
::For floats only: returns the mantissa, such that the number's value is:<br> "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.<br>For example, "<CODE>FloatD fmin</CODE>" 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.<br>For example, "<CODE>FloatD fmax</CODE>" 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.<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). |
|||
|
|||
:''aNumber'' '''isComplex''' => Boolean |
|||
::Check if number is a complex number. |
::Check if number is a complex number. |
||
|
|
||
''aNumber'' |
:''aNumber'' '''negative''' => Boolean |
||
::same as <code>''aNumber'' < 0</code> |
::same as <code>''aNumber'' < 0</code> |
||
|
|
||
''aNumber'' |
:''aNumber'' '''positive''' => Boolean |
||
::same as <code>''aNumber'' >= 0</code> |
::same as <code>''aNumber'' >= 0</code> |
||
|
|
||
''aNumber'' |
:''aNumber'' '''strictlyPositive''' => Boolean |
||
::same as <code>''aNumber'' > 0</code> |
::same as <code>''aNumber'' > 0</code> |
||
|
|
||
''anInteger'' |
:''anInteger'' '''isPrime''' => Boolean |
||
::true if the number is a prime number |
::true if the number is a prime number |
||
|
|
||
''anInteger'' |
:''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 |
||
|
|
||
''anInteger'' |
:''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 |
||
|
|||
''anInteger'' <code>nextPrime</code> => anInteger |
|||
<br>''anInteger'' <code>nextPowerOf2</code> => anInteger |
|||
|
|
||
=== Arithmetic === |
=== Arithmetic === |
||
''aNumber'' |
:''aNumber'' '''+''' ''aNumber'' => Number |
||
:''aNumber'' '''-''' ''aNumber'' => Number |
|||
:''aNumber'' '''*''' ''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. |
||
|
|||
''aNumber'' |
:''aNumber'' '''**''' ''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> |
||
|
|||
''aNumber'' |
:''aNumber'' '''//''' ''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> |
||
|
|||
''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> |
||
|
|||
:''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: |
||
:''aNumber'' '''ln''' => Number |
|||
:''aNumber'' '''log10''' => Number |
|||
:''aNumber'' '''log2''' => 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 |
::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; |
|||
:If the error is explicitly ignored with <code>Error ignoreIn:[ aNumber ln]</code>, you'll get NaN. |
|||
::to get a complex result, use "<code>Complex trapImaginary:[ aNumber ln ]</code>". |
|||
|
|
||
''aNumber'' |
:''aNumber'' '''sqrt''' => 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>". |
||
:If the error is explicitly ignored, you'll get NaN. |
|||
|
|
||
''aNumber'' |
:''aNumber'' '''cbrt''' => Number |
||
:''anInteger'' '''integerCbrt''' => Integer |
|||
: |
::cubic root and truncated cubic root. |
||
|
|
||
''aNumber'' |
:''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:". |
|||
|
|
||
''aNumber'' |
:''aNumber'' '''exp''' => Number |
||
:''number1'' '''raisedTo:''' ''number2'' => Number |
|||
:''number1'' '''**''' ''number2'' => Number |
|||
::exponentiation; the "<code>**</code>" binary operator is an alias for "<code>raisedTo:</code>". |
|||
<br>''aNumber'' <code>cot</code> => Number (cotangent) |
|||
|
|||
<br>''aNumber'' <code>sec</code> => Number (secant) |
|||
<br>''aNumber'' <code>csc</code> => Number (cosecant) |
|||
:''aNumber'' '''sin''' => Number |
|||
:''aNumber'' '''cos''' => Number |
|||
:''aNumber'' '''tan''' => 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 |
|||
|
|||
:''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'' |
:''integer1'' '''bitAnd:''' ''integer2'' => Integer |
||
:''integer1'' '''bitOr:''' ''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 |
|||
:''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 437: | 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'' |
:''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. |
::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. |
::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 460: | 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'' |
''aNumber'' '''printfPrintString:''' ''formatString'' => String |
||
</div> |
</div> |
||
::Examples: |
::Examples: |
||
Zeile 469: | 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 ( |
:: 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) |
||
|
|||
:''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 |
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 |
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. |
||
: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 |
||
:Number '''readFrom:''' ''aStream'' '''onError:'''[ ''errorValue'' ] => someNumber or errorValue |
|||
:: 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 <code>value</code> 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'' ]</code> => 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, but these will return a |
:: 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". |
|||
:''aNumber'' '''asInteger''' => Integer |
|||
::truncates |
::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). |
|||
:''aNumber'' '''asShortFloat''' => Float32 |
|||
:''aNumber'' '''asFloat32''' => Float32 |
|||
::truncates (i.e. same as "truncated") |
|||
:''aNumber'' '''asFloatE''' => Float32 |
|||
::generates |
::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 |
::same as above, but reports an error if the value cannot be represented (instead of returning INF). |
||
:''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. |
||
:''aNumber'' '''asLongFloatChecked''' => Float80 or error |
|||
::same as above, but |
::same as above, but reports an error if the value cannot be represented (instead of returning INF). |
||
:''aNumber'' '''asQDouble''' => QDouble |
|||
::generates a qDouble |
::generates a qDouble |
||
:''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) |
|||
:''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) |
||
:''aNumber'' '''asScaledDecimal:''' ''scale'' => ScaledDecimal |
|||
::generates a scaled decimal which presents ''scale'' fractional digits |
::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 |
::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") |
::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' |
|||
'%.50g' printf:{nr} |
'%.50g' printf:{nr} |
||
=> '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' |
|||
'%.50g' printf:{nr} |
'%.50g' printf:{nr} |
||
=> '1.4142135623730950488016887242096980785696718753769' |
|||
'%.100g' printf:{nr} |
'%.100g' printf:{nr} |
||
=> '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) |
|||
'%.50g' printf:{nr} |
'%.50g' printf:{nr} |
||
=> '1.4142135623730950488016887242096980785696718753769' |
|||
'%.100g' printf:{nr} |
'%.100g' printf:{nr} |
||
=> '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' |
|||
'%.50g' printf:{nr} |
'%.50g' printf:{nr} |
||
=> '1.4142135623730950488016887242096980785696718753769' |
|||
'%.100g' printf:{nr} |
'%.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 ==== |
|||
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 605: | 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 |
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 634: | 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 |
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 642: | Zeile 955: | ||
The Smalltalk implementation takes the former approach. |
The Smalltalk implementation takes the former approach. |
||
The |
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 661: | Zeile 974: | ||
** %e, %E, %f, %g always show decimal point |
** %e, %E, %f, %g always show decimal point |
||
Conversions |
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 668: | 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 685: | Zeile 998: | ||
Dynamic width/precision (consumed in order as presented): |
Dynamic width/precision (consumed in order as presented): |
||
* "*" |
* "*" 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 719: | 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 734: | 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 752: | 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 770: | 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, 11: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
Inhaltsverzeichnis
- 1 Literals (i.e. Constant Numbers)
- 2 Wellknown Constant Numbers
- 3 Float Representations
- 4 Fractions
- 5 Scaled Decimals
- 6 Fixed Decimals
- 7 Number Ranges
- 8 Complex Numbers
- 9 Measurement Values
- 10 Physical Values
- 11 Operations with Mixed Types
- 12 Most Common/Useful Operations
- 13 Examples
- 14 Printf Format Specifier
- 15 Scanf Format Specifier
- 16 See Also
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
- for example,
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)
- Check if number is NaN ("Not a Number"). Notice that there are multiple representations of "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)".
- For floats only: returns the exponent, such that the number's value is:
- aNumber mantissa => Integer
- For floats only: returns the mantissa, such that the number's value is:
"mantissa * (2 ^ exponent)".
- For floats only: returns the mantissa, such that the number's value is:
- 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.
- For float classes only: returns the smallest representable (normalized) number of that class.
- 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.
- For float classes only: returns the largest representable number of that class.
- 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).
- For float classes only: returns the smallest and largest possible exponent representable by numbers of that class.
- aNumber isComplex => Boolean
- Check if number is a complex number.
- aNumber negative => Boolean
- same as
aNumber < 0
- same as
- aNumber positive => Boolean
- same as
aNumber >= 0
- same as
- aNumber strictlyPositive => Boolean
- same as
aNumber > 0
- same as
- 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.
- 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.
- The usual arithmetic operators.
- 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:
- Truncated result and remainder (towards the next smaller integer i.e. towards negative infinity).
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:
- Truncated result (towards zero) and corresponding remainder.
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 ]
".
- square root and truncated square root
- 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.
- the nth root.
- aNumber exp => Number
- number1 raisedTo: number2 => Number
- number1 ** number2 => Number
- exponentiation; the "
**
" binary operator is an alias for "raisedTo:
".
- exponentiation; the "
- 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.
- returns the next larger integer (unless aNumber is integral).
- aNumber floor => Number
- returns the next smaller integer (unless aNumber is integral).
E.g. truncates towards negative infinity.
- returns the next smaller integer (unless aNumber is integral).
- 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".
- truncates towards the nearest multiple of grid.
- 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".
- rounds up/down towards the nearest multiple of grid.
- 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".
- rounds up/down for n valid digits.
- 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".
- rounds up/down for n decimal fraction digits.
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).
- the factorial; i.e. "
- 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).
- the nth Fibonacci number. Huge numbers are to be expected (try "
- 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)
- an approximation of the nth Fibonacci number according to Binet.
- 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.
- 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
- 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 is a printf/scanf-like format string; reads items from aString and returns a collection (i.e. an Array) of scanned objects.
- 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.