 # The problem of R1 controller floating point number accumulation

Both variables are floating-point numbers. When a floating-point number is large, the accumulation function cannot be completed. How to solve it?

Thanks.

EDIT. Not what are you doing in the software, Philip has answered that, but what is your process trying to do? Why is it so fast over a long period of time?
What is the process?

That is an inherit limitation of floating point numbers.

You can’t add a small number to a large number past a certain point as there is not enough precision to represent the new number.

You’re trying to store 3102200.019 into a float - which it can’t represent so it rounds it to 3102200. Basically you can only hold about 7 or 8 significant digits in a 32 bit float.

A quick fix would be to increase the period you take the measurements so the small number isn’t so small.

1 Like

Looks like what you are try to do is accumulate flow by adding the amount of flow from the last period. The variable Flow_5xt_Period is a floating point type. What type of variable is Flow_5xt_Total?
If Flow_5xt_Total is an integer than adding 0.019, from your screenshot, is not a large enough value for it to round up to be 1.

A better method would be to store your accumulators in a 64 bit integer. For example, if your units are liters and you want a resolution to 3 decimal place - then have your accumulator record in mL.

``````//The int 64 would be your persistent accumulator, Flow_5xt_Period is still a float here
n64Flow_5xt_Total_mL = n64Flow_5xt_Total_mL + (Flow_5xt_Period * 1000);
//Your float would continue to be used for the HMI / data logging:
Flow_5xt_Total = n64Flow_5xt_Total_mL / 1000.0;``````

Thank you, my friends. The problem has been solved. It’s working normally.

//Flow_3xt_Total is int32，The rest are floating-point numbers
if(IsFloatValid(Flow_3xt_Period)) then
Flow_3xt_Period_Accu=Flow_3xt_Period_Accu+Flow_3xt_Period;
if(Flow_3xt_Period_Accu>1) then
Flow_3xt_Total=Flow_3xt_Total+truncate(Flow_3xt_Period_Accu);
Flow_3xt_Period_Accu=Flow_3xt_Period_Accu-truncate(Flow_3xt_Period_Accu);
endif

endif

endif