Number API Functions: Unterschied zwischen den Versionen

Aus expecco Wiki (Version 2.x)
Zur Navigation springen Zur Suche springen
Zeile 426: Zeile 426:
<code>Number fomString:</code> ''aString'' => someNumber or error
<code>Number fomString:</code> ''aString'' => someNumber or error
<br><code>Number fromString:</code> ''aString'' <code>onError:</code>[ ''errorValue'' ]</code> => someNumber or fallBackValue
<br><code>Number fromString:</code> ''aString'' <code>onError:</code>[ ''errorValue'' ]</code> => someNumber or fallBackValue

<code>Integer readFrom:</code> ''aStream''
<code>Integer readFrom:</code> ''aStream'' <code>onError:[...]</code>
<br><code>Float readFrom:</code> ''aStream''
<br><code>Float readFrom:</code> ''aStream'' <code>onError:[...]</code>
<br><code>Integer fromString:</code> ''aStream''
<br><code>Integer fromString:</code> ''aStream'' <code>onError:[...]</code>
<br><code>Float fromString:</code> ''aStream''
<br><code>Float fromString:</code> ''aStream'' <code>onError:[...]</code>
:: similar, but these will return a corresponding typed number


=== Truncation and Rounding ===
=== Truncation and Rounding ===

Version vom 23. September 2021, 10:19 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.

Reference: Integer, Float, Fraction, ScaledDecimal, Complex which all inherit from Number

Back to Useful API Functions

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

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

Integer Literals[Bearbeiten]

1234
16rFFAA
or 0xaffe
2r0101
or 0b101010
8r377
or 0o377
NrXXX
1234567890123456789012345678901234567890
-123456789012345678901234567890

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
1345.6789q5

float constant; actually double precision;
use "q" instead of "e" for extra precision (extended IEEE floats)
Fraction Literals[Bearbeiten]

(4/3)
(523423432/3)

fraction constants (numerator / denominator); these are exact
Scaled Decimal Literals[Bearbeiten]

123.456s2
100s2

scaled decimal; prints itself rounded to 2 fractional digits eg. "123.46" or "100.00" (although internally, the full precision is kept for further operations)
Complex Number Literals[Bearbeiten]

(4+3i)
(4.3+3.1i)
5.0 i

a complex number (real part / imaginary part)

Wellknown Constant Numbers[Bearbeiten]

A few constants are known by name. They are answered by corresponding getter messages sent to the number class (of which you want the constant):

Float pi

pi as IEEE double precision number

LongFloat pi

pi as IEEE extended precision number

Float ln2
Float ln10
Float phi
Float sqrt2
Float e

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)".

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.
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). Scaled decimals are perfect to present values to a user or in a report in a "human friendly" rounded format.

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.

Banks may want to keep the round-off differences in their own pocket, they use "truncatedToScale".

Fixed Decimals[Bearbeiten]

(new with expecco 21.2)
Similar to Scaled Decimals, 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 on an invoice's summation.

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

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

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. square root (sort) and logarithm (log, ln) operations IFF imaginary results are trapped. I.e.

-4 sqrt

will report an error, whereas:

Number trapImaginary:[ -4 sqrt ]

will return a complex result.

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 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")

Operations with Mixed Types[Bearbeiten]

Normally, there is no need for explicit conversion between number types. The result of mixed operations is the computed with the type of the operand which has the higher "generality". The order of generalities is:

Integer < Fraction < ScaledDecimal < FixedDecimal < Float32 < Float64 < Float80 < 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.

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" yields "(20 ± 1)".

aMeasurementValue * aNumber => MeasurementValue
aMeasurementValue / aNumber => MeasurementValue

the error will also be scaled by aNumber. Eg. "(10 ± 1) * 10" yields "(100 ± 10)".

 

PhysicalValues[Bearbeiten]

PhysicalValues can only be scaled by a scalar value; addition and subtraction are not allowed:

aPhysicalValue + aNumber => error
aPhysicalValue - aNumber => error

not allowed

aPhysicalValue * aNumber => aPhysicalValue
aPhysicalValue / aNumber => aPhysicalValue

for example, "10 volt * 10" gives "100 volt".

 

Most Common/Useful Operations[Bearbeiten]

Testing[Bearbeiten]

aNumber isFinite => Boolean

Check if number is not infinity and not NaN:

 

aNumber isInfinite => Boolean

Check if number is either positive infinity (INF) or negative infinity (-INF):

 

aNumber isNaN => Boolean

Check if number is NaN ("Not a Number"):

 

aNumber isInteger => Boolean

Check if number is an integral number.

 

aNumber isFraction => Boolean

Check if number is a fractional number.

 

aNumber isComplex => Boolean

Check if number is a complex number.

 

aNumber negative => Boolean

same as aNumber < 0

 

aNumber positive => Boolean

same as aNumber >= 0

 

aNumber strictlyPositive => Boolean

same as aNumber > 0

 

anInteger isPrime => Boolean

true if the number is a prime number

 

anInteger isPowerOf2 => Boolean

true if there exists an n, such that 2ˆn equals the number

 

anInteger isPowerOf:b => Boolean

true if there exists an n, such that bˆn equals the number

 

anInteger nextPrime => anInteger
anInteger nextPowerOf2 => anInteger  

Arithmetic[Bearbeiten]

aNumber + aNumber => Number
aNumber - aNumber => Number
aNumber * aNumber => Number
aNumber / aNumber => Number

The usual arithmetic operators.
All of the above allow operands of any number type, and will generate a result as appropriate. When dividing integers, an exact result is returned (either integer or fraction). If any of the arguments is inexact (i.e. a floating point number), the result will be inexact. If both are exact, the result will be exact. Fractional results are reduced to the greatest common divisor as denominator.
Point right.png Notice, that they are evaluated 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.

aNumber ** aNumber => Number
aNumber raisedTo: aNumber => Number

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

aNumber // aNumber => Integer
aNumber \\ aNumber => Integer

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

aNumber quo: aNumber => Integer
aNumber rem: aNumber => Integer

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

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

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 ]".

 

aNumber cbrt => Number
aNumber integerCbrt => Number

cubic root and truncated cubic root.

 

aNumber exp => Number
number1 raisedTo:number2 => Number
number1 **number2 => Number

exponentiation; the "**" binary operator is an alias for "raisedTo:".

 

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

trigonometric functions


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

hyperbolic functions

Bitwise Operators[Bearbeiten]

integer1 bitAnd:integer2 => Integer
integer1 bitOr:integer2 => Integer
integer1 bitXor:integer2 => Integer
integer1 bitShift:count => Integer

left shift if count is positive; right shift if negative


integer1 leftShift:count => Integer
integer1 rightShift:count => Integer
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


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 (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)

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.
  • when converting from a string, no extra characters are expected/allowed after the number's digits, except for whitespace. Thus you'll usually get an error when trying to convert a string with garbage characters after the number (which is not the case when reading from a stream).

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

Numbers are read by sending the Number-class a "readFrom:" or a "fromString:" message. If the class is the abstract class Number, then the read code will itself figure out, what kind of number to return. If the given class is a concrete class (Float, Integer, Fraction etc.), you will get an instance of that class, unless the characters o not represent a valid number (of that class). 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 any of the number types


Number readFrom: aStream onError:[ errorValue ] => someNumber or errorValue

errorValue (which is a Smalltalk block), can be a constant, an arbitrary Smalltalk expression or even show a warn dialog or do whatever you like

Number fomString: aString => someNumber or error
Number fromString: aString onError:[ errorValue ] => someNumber or fallBackValue

Integer readFrom: aStream Integer readFrom: aStream onError:[...]
Float readFrom: aStream
Float readFrom: aStream onError:[...]
Integer fromString: aStream
Integer fromString: aStream onError:[...]
Float fromString: aStream
Float fromString: aStream onError:[...]

similar, but these will return a corresponding typed number

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 (i.e. same as "truncated")


aNumber asFloat => Float64

generates double precision float; may generate +/- INF if the value cannot be represented as a double IEEE float.


aNumber asFloatChecked => Float64 or error

same as above, but generates an error if the value cannot be represented.


aNumber asShortFloat => Float32

generates single precision float; may generate +/- INF if the value cannot be represented as a single IEEE float.


aNumber asShortFloatChecked => Float32 or error

same as above, but generates an error if the value cannot be represented.


aNumber asLongFloat => 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 generates an error if the value cannot be represented.


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")



Copyright © 2014-2024 eXept Software AG