Arithmetic in Expression Language

Modified on Wed, Nov 29, 2023 at 10:29 AM

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
    1. Integer
    2. Long – larger integers

Figure 1 - Excerpt from the Student table schema showing Integer Data Types

 

  • Decimal Data Types
    1. Double – Old “larger decimal” data type
    2. Float – Old “smaller decimal” data type
    3. 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:
    1. rw:multiplyBigDecimal
  • Division – To do division, the divideBigDecimals or divideBigDecimalsWithScale functions must be used:
    1. ${rw:divideBigDecimalsWithScale (row.someBigDecimal,row.anotherBigDecimal, 2)}
    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
    3.  
  • 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:
    1. 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

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article