Helm template float arithmetic

$ helm version
version.BuildInfo{Version:"v3.3.0", GitCommit:"8a4aeec08d67a7b84472007529e8097ec3742105", GitTreeState:"dirty", GoVersion:"go1.14.6"}

So I have my template:

  minAvailable: {{ mul .Values.autoscaling.minReplicas 0.75 }}

values.yaml:

autoscaling:
  minReplicas: 3

I would have expected a rendered output of 2.25, but I get 0 (3 * 0 because 0.75 gets floored...)

I've tried things like

  minAvailable: {{ mul (float .Values.autoscaling.minReplicas) 0.75 }}

Ultimately I'm going to floor the value to get back to an int...

  minAvailable: {{ floor ( mul .Values.autoscaling.minReplicas 0.75 ) }}

But I just don't understand why I can't seem to do simple float arithmetic


Other things I've tried

  minAvailable: {{ float64 .Values.autoscaling.minReplicas }} 
  minAvailable: {{ float64 .Values.autoscaling.minReplicas | toString }} 

nothing produces a float number....

I've even tried doing this in values.yaml

autoscaling:
  minReplicas: 3.0

Solution 1:

These arithmetic functions aren't part of the core Go text/template language. They come from a package of useful extensions called Sprig that Helm includes. In particular, the documentation for its Math Functions states at the top of the page

All math functions operate on int64 values unless specified otherwise.

Instead of trying to calculate floating-point x * 0.75, you could calculate integer x * 3 / 4. Factor this as (x * 3) / 4 and you can do this as reasonably precise integer arithmetic:

minAvailable: {{ div (mul .Values.autoscaling.minReplicas 3) 4 }}

Solution 2:

Helm and its templates support the default Go text/template functions and the function provided by the Sprig extension. Since Sprig version 3.2 it also supports Float Math Functions like addf, subf, mulf, divf, etc. In your case you would just need:

  minAvailable: {{ mulf .Values.autoscaling.minReplicas 0.75 }}