The math filters (plus, minus, times, modulo) always return float regardless of input types. This differs from Shopify/Liquid's behavior where:
- Integer + Integer → Integer
- Float involved → Float
- String integers (e.g.,
'20') → treated as Integer
- String decimals (e.g.,
'20.0') → treated as Float
Currently, all math filters use (float) cast unconditionally, which breaks compatibility with Shopify/Liquid.
Examples
plus
| Template |
Expected (Shopify) |
Current (php-liquid) |
{{ 1 | plus:1 }} |
2 (int) |
2.0 (float) |
{{ '1' | plus:'1.0' }} |
2.0 (float) |
2.0 (float) ✓ |
minus
| Template |
Expected (Shopify) |
Current (php-liquid) |
{{ 5 | minus:1 }} |
4 (int) |
4.0 (float) |
{{ '4.3' | minus:'2' }} |
2.3 (float) |
2.3 (float) ✓ |
times
| Template |
Expected (Shopify) |
Current (php-liquid) |
{{ 3 | times:4 }} |
12 (int) |
12.0 (float) |
{{ 'foo' | times:4 }} |
0 (int) |
0.0 (float) |
{{ 0.0725 | times:100 }} |
7.25 (float) |
7.25 (float) ✓ |
modulo
| Template |
Expected (Shopify) |
Current (php-liquid) |
{{ 3 | modulo:2 }} |
1 (int) |
1.0 (float) |
Refs
The math filters (
plus,minus,times,modulo) always returnfloatregardless of input types. This differs from Shopify/Liquid's behavior where:'20') → treated as Integer'20.0') → treated as FloatCurrently, all math filters use
(float)cast unconditionally, which breaks compatibility with Shopify/Liquid.Examples
plus
{{ 1 | plus:1 }}2(int)2.0(float){{ '1' | plus:'1.0' }}2.0(float)2.0(float) ✓minus
{{ 5 | minus:1 }}4(int)4.0(float){{ '4.3' | minus:'2' }}2.3(float)2.3(float) ✓times
{{ 3 | times:4 }}12(int)12.0(float){{ 'foo' | times:4 }}0(int)0.0(float){{ 0.0725 | times:100 }}7.25(float)7.25(float) ✓modulo
{{ 3 | modulo:2 }}1(int)1.0(float)Refs
apply_operation: https://github.com/Shopify/liquid/blob/32b50ecafecae41b924f3e3120c6dc587efdd800/lib/liquid/standardfilters.rb#L1003-L1006Utils.to_number: https://github.com/Shopify/liquid/blob/32b50ecafecae41b924f3e3120c6dc587efdd800/lib/liquid/utils.rb#L51-L66