Number API 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.
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.