Felic, you have made a common math error, called “extending the precision”.

What do you get if you divide 4 by 7?

0.57142857142857142857142857142857

NO. 4 and 7 are given to single figure accuracy. A more correct answer is 0.6

Your voltage readings can not have more than 0.25% accuracy and may be a LOT worse depending on the reference voltage you use.

Secondly, you are taking readings from a graph that shows the behaviour of a population, and applying it to an individual case. But you dont know how the population was distributed.

Start by looking again at the graph. Having done many battery discharge tests with my data logger I can state the following. (see also https://eu.industrial.panasonic.com/sites/default/pidseu/files/downloads/files/id_alkaline_1203_e.pdf)

1: the open-circuit voltage of a fresh cell is between 1.5 and 1.7V

2: on load the voltage drops to about 1.4 when it is about 10% discharged.

3: The voltage you measure will depend on the load current.

4: when the battery has only about 10% charge left its voltage will start to drop much more sharply.

5: EVERY battery will be different.

6: the graph is only representative of the discharge current used.

(Also, a useful arduino circuit will generally draw a lot more than “like 1mA” as you said initially)

So the simplest and most realistic approach is to ignore the first and last 10% and use interpolation between the 10% and 90% points.

at 10% the voltage is AROUND 1.4V (NOT 1.40000000000)

at 90% the voltage is AROUND 1.1V

Lets say your scaling factor is 0=0V and 1023 = 2.096V you your reading N is 700 for 1.4V and 540 for 1.08V (I’ve chosen that to make the math numbers easy: 700-540 = 160)

we do a straight line fit 700=90%, 540 = 10% to find the remaining percentage P

then:

if N > 701 let P = 100;

if N = (700 - 540) P = 90 - (700 - N) /2 ;

if N <539 let P = 0;

If you MUST have (unrealistic) values in the 0-10% && 90-100% ranges I’d probably use a switch case structure such as

Switch (N)

case >750 P=98;

case 740 … 749 P=96;

…

case 540 … 700 {P = 90 - (700 - N) / 2 ;} //use a right shift

case 530 …539 P=8;

etc.

And of course for 2 cells in series, you should really measure each seperately.