Number API Functions: Unterschied zwischen den Versionen
Cg (Diskussion | Beiträge) |
Cg (Diskussion | Beiträge) |
||
Zeile 957: | Zeile 957: | ||
* <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. |
* <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: |
Examples <sup>1)</sup>: |
||
'|%d|' printf: { 123 } -> '|123|' |
'|%d|' printf: { 123 } -> '|123|' |
||
'|%5d|' printf: { 123 } -> '| 123|' |
'|%5d|' printf: { 123 } -> '| 123|' |
||
Zeile 1.009: | Zeile 1.009: | ||
'% 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. |
|||
== Scanf Format Specifier == |
== Scanf Format Specifier == |
Version vom 29. Januar 2022, 11:01 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 Complex Numbers
- 8 Measurement Values
- 9 Physical Values
- 10 Operations with Mixed Types
- 11 Most Common/Useful Operations
- 12 Examples
- 13 Printf Format Specifier
- 14 Scanf Format Specifier
- 15 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 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 eg. "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 = FloatF (=ShortFloat), Float64 = FloatD (=Float) and Float80 = FloatQ (=LongFloat).
There is usually no need to explicitly use or refer to ShortFloats (or FloatFs): 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.
ShortFloat / FloatF / 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.
Floats print themself with either a decimal point or an exponent indicator 'e', eg. "0.5", "10.0" or "1.3e3"
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 eg. 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. 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. 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).
However, this will look strange (i.e. wrong) if monetary values are presented this way, eg. on an invoice's summation. Here, we expect a sum of amounts to be the sum of previously listed values (think of sales tax being computed, giving a rounded Cent-value). 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 eg. 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 eg. in an invoice's sum.
Be aware that converting a float to a FixedDecimal and back will not necessarily return the starting number. Unlike ScaledDecimals, FixedDecimals do NOT preserve the original value.
If you have a pre 21.2 version, the FixedDecimal behavior can be "simulated" by forcing the scaled decimal to round its value to the shown scale (as described above).
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 (eg. "5 i" yields (0 + 5 i).
Complex numbers print themself as "(a + b i)".
Complex results can also be returned from eg. 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 parts 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 (eg. 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).
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.
- Eg. (10 ± 1) + 10 => (20 ± 1).
- aMeasurementValue * aNumber => MeasurementValue
- aMeasurementValue / aNumber => MeasurementValue
- the error will also be scaled by aNumber.
- Eg. (10 ± 1) * 10 => (100 ± 10).
Mixed Operations with PhysicalValues[Bearbeiten]
PhysicalValues can only be scaled by a scalar value; addition and subtraction are not allowed (except for addition/subtraciton of same unit values):
- aPhysicalValue + aNumber => error
- aPhysicalValue - aNumber => error
- not allowed
- aPhysicalValue * aNumber => PhysicalValue
- aPhysicalValue / aNumber => PhysicalValue
- for example, 10 volt * 10 => 100 volt.
Most Common/Useful Operations[Bearbeiten]
Testing[Bearbeiten]
- aNumber
isNaN
=> Boolean- 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": "Float32 NaN", "Float64 NaN" etc.
- 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 - aNumber
integerSqrt
=> Number- 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- 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:".
- 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
Statistical / Combinatorical Functions[Bearbeiten]
- anInteger
factorial
=> Integer- the factorial; i.e. "n factorial" is 2*3*4...*n". Huge numbers are to be expected (try "1000 factorial inspect" in a workspace).
- n
binomialCoefficient:
k => Integer - n
binco:
k => Integer- the binomial coefficient (aka. n over k or the number of ways of picking k unordered outcomes from n possibilities)
- n
agm:
y => Float- the arithmetic-geometric mean
Other Special Functions[Bearbeiten]
- integer1
gcd:
integer2 => Integer- the greatest common divisor of integer1 and integer2.
- integer1
lcm:
integer2 => Integer- the least common multiple of integer1 and integer2.
- anInteger
fib
=> Integer- the nth Fibonacci number. Huge numbers are to be expected (try "1000 fib inspect" in a workspace).
- aNumber
fib_binet
=> Float- an approximation of the nth Fibonacci number according to Binet.
For example, "5000 fib_binet" gives: "1.0777734893072974780...e+10449" (by default with 200 bits precision)
- 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:
aStreamradix:
base => void - aNumber
printOn:
aStreamleftPaddedTo:
length => void - aNumber
printOn:
aStreamleftPaddedTo:
lengthwith:
padCharacter => void - aNumber
printOn:
aStreampaddedTo:
length => void - aNumber
printOn:
aStreampaddedTo:
lengthwith:
padCharacter => void - aNumber
printString
=> String - aNumber
printStringRadix:
base => String - aNumber
printStringLeftPaddedTo:
length => String - aNumber
printStringLeftPaddedTo:
lengthwith:
padCharacter => String - aNumber
printStringPaddedTo:
length => String - aNumber
printStringPaddedTo:
lengthwith:
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 (eg. 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:
aStreamonError:
[ errorValue ] => someNumber or errorValue- errorValue (which is a Smalltalk block), can be a constant, an arbitrary Smalltalk expression or even show a warn dialog or do whatever you like. In case of an error, the value returned from the read method will be the value provided by the error-block.
- Number
fromString:
aString => someNumber or error - Number
fromString:
aStringonError:
[ errorValue ] => someNumber or fallBackValue- similar, but does not allow for garbage characters after the number (except spaces)
- Integer
readFrom:
aStream - Integer
readFrom:
aStreamonError:
[...] - Float
readFrom:
aStream - Float
readFrom:
aStreamonError:
[...] - Integer
fromString:
aStream - Integer
fromString:
aStreamonError:
[...] - Float
fromString:
aStream - Float
fromString:
aStreamonError:
[...]- 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.
Truncation and Rounding[Bearbeiten]
- aNumber
truncated
=> Integer- truncates towards zero
- aNumber
rounded
=> Number- rounds up/down towards the nearest integer
- aNumber
ceiling
=> Number- returns the next larger integer (unless aNumber is integral). I.e. truncates towards positive infinity.
- aNumber
floor
=> Number- returns the next smaller integer (unless aNumber is integral). I.e. truncates towards negative infinity.
- aNumber
roundTo:
grid => Number- rounds up/down towards the nearest multiple of grid. I.e. "1.284 roundedTo:0.1" yields "1.3".
- aNumber
truncateTo:
grid => Number- truncates towards the nearest multiple of grid. I.e. "1.284 truncateTo:0.1" yields "1.2".
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- 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 is an alias.
- aNumber
asFloatChecked
=> Float64 or error- same as above, but reports an error if the value cannot be represented.
- aNumber
asShortFloat
=> Float32 - aNumber
asFloat32
=> Float32- generates a single precision float; may generate +/- INF if the value cannot be represented as a single IEEE float. asFloat32 is an alias.
- aNumber
asShortFloatChecked
=> Float32 or error- same as above, but reports an error if the value cannot be represented.
- 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.
- 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- generates a complex (with 0 as real part, eg. 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 will 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 Smalltalk implementation takes the former approach, handling '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 Smalltalk implementation 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
- 'T' and 'V' for JS typeof and valueOf inspection
- 'S' for store-string
- 'P' for print-string
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 (upper case same as lower case, except for xX):
- '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 value)
- 'i' integer (alias for 'd')
- 'j' (not implemented) 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.
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.