Arithmetic - Working with Numbers in Expressions
Integer Arithmetic vs Decimal Arithmetic in Expression Language
In computing integer arithmetic is very different than decimal arithmetic. Integers – whole numbers – are stored very simply while decimal numbers have to be stored as two parts: the “whole number” part and “the fractional part”. This creates the need to have two completely separate types of arithmetic:
- Integer arithmetic
- Decimal arithmetic
Data Types and Arithmetic
The type of data you have – integer vs decimal – dictates how you must do arithmetic (if you are doing arithmetic). When you look at the schema for a database table, the “Data Type” column will tell you which you have.
- Integer Data Types
- Integer
- Long – larger integers
Figure 1 - Excerpt from the Student table schema showing Integer Data Types
- Decimal Data Types
- Double – Old “larger decimal” data type
- Float – Old “smaller decimal” data type
- BigDecimal – Decimals that can be used for arithmetic.
Figure 2 - Excerpts from the Student table schema showing Decimal Data Types
The Double and Float data types use an older format and do not give accurate answers when used for arithmetic. To do arithmetic with decimal numbers, you must convert them to BigDecimals and do BigDecimal arithmetic (see below).
Expression Language supports the usual set of arithmetic operators: Add ('+'), Subtract ('-'), Multiply ('*') and Divide ('/') as well as 'Modulo ("%")'. Modulo is the same as "integer remainder"
Numeric constants (i.e. "numeric literals") can be used directly.
Rows can be added, subtracted, multiplied and divided. Division must use BigDecimal arithmetic described below.
- Sum several rows together: ${row.payment1 + row.payment2 + row.payment3}
- Average several rows: ${(row.score1 + row.score2 + row.score3)/3.0}
- Multiply rows or values: ${row.weight * row.grade}, ${row.assignmentGrade * params.CountGradesThisManyTimes}
- Find Integer Remainder: ${10%4} - The integer remainder of "10%4" (10 modulo 4) is 2.
- Division: while there is a simple division operator in Expression Language, the ‘/’ symbol, because division is likely to end up with a decimal number instead of another integer, it is not safe to do simple ‘/’ division in Expression Language – you should switch to Decimal arithmetic when doing division. See below.
All arithmetic in ReportWriter should be done with Expression columns.
Decimal Arithmetic in Expressions: BigDecimals
Decimal arithmetic, unlike integer arithmetic, must be done with a specific set of “BigDecimal” functions.
What are Big Decimals?
“BigDecimal” is a newer format for decimal numbers that enables accurate decimal calculations.
- Addition: Currently, in the SIS (but not SchoolFi) the ‘+’ plus operator can be used to add two BigDecimals.
- Subtraction: Currently, in the SIS (but not SchoolFi) the ‘-‘ minus operator can be used to subtract two BigDecimals.
- Multiplication – To do multiplication, the multiplyBigDecimal function must be used:
- rw:multiplyBigDecimal
- Division – To do division, the divideBigDecimals or divideBigDecimalsWithScale functions must be used:
- ${rw:divideBigDecimalsWithScale (row.someBigDecimal,row.anotherBigDecimal, 2)}
- E.g. Divide student's total days present (170) by total days enrolled (180) would appear like this: ${rw:divideBigDecimalsWithScale (row.cumulativeDaysPresent, row.cumulativeDaysInMembership, 2)} The result would be "0.9
- Converting fields to BigDecimal format: an integer, another decimal data type (e.g. Double), or a String can be converted to a BigDecimal by using the “toBigDecimal” function:
- rw:toBigDecimal(row.someColumn)
Number Functions in Expression Language
BigDecimal divideBigDecimals(BigDecimal value1, BigDecimal value2)
Divides Big Decimal numbers
Usage: ${rw:divideBigDecimals(value1, value2)}
BigDecimal divideBigDecimalsWithScale(BigDecimal value1, BigDecimal value2, int scale)
Divides Big Decimal numbers rounding to the nearest scale.
Usage: ${rw:divideBigDecimalsWithScale(value1, value2, scale)}
String formatNumber(Object value, String pattern)
Returns a formatted string for any Numeric type using the pattern.
Usage: ${rw:formatNumber(value, pattern)}
BigDecimal multiplyBigDecimals(BigDecimal value1, BigDecimal value2)
Multiplies Big Decimal numbers
Usage: ${rw:multiplyBigDecimals(value1, value2)}
Was this article helpful?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article