analogRead() returns type int. So, look at this line:
volts = volts + (analogRead(A1) * 5 / 1023); //if "5" is changed to "5.0" it works
Say you in feed 2.5V, for a 5V reference voltage you'll get about mid-scale (512). 512 * 5 is performed as an integer multiplication, yielding another
integer value of 2560. 1023 is also an integer, so 2560/1023 is performed as an integer division. An integer cannot represent 2.5, it can only represent whole numbers. By the convention in the C standard, the quotient (floor) is returned from the division, so you get 2 as an output, which is then cast to a float (2.00).
The reason it works if you change the 5 to 5.0 is because the first multiplication is now 512 (int) * 5.0 (float), which creates an implicit cast, evaluating the whole calculation in floating point.
To be perfectly clear as to what sort of operations are happening, I would have personally written the line like so:
volts = volts + ( (float) analogRead(A1) * 5.0 / 1023.0);
The constants are explicitly floating-point, and the analogRead value has been explicitly cast to float. This way, it's now clear that everything is operating in floating point, as you intend it.
Your v1 calculation has a similar problem:
v1 = 5.0*(analogRead(A1)/1023);
In this case, the division in the brackets is evaluated first, which is an int/int division. Since 0 <= analogRead <= 1023, the division evaluates to less than 1 for all values of analogRead less than 1023. As we learned before, integer division returns the quotient (ie: the floor), so this will always come out to 0 for values of analogRead less than 1023, and 1 if analogRead is exactly equal to 1023. This integer value is implicitly cast to a float when it is multiplied by 5.0, however, it is already either 0 or 1, so v1 will always be either 0.0 or 5.0
As for your measured voltage being incorrect, yes, that would certainly be the case if your board voltage is 4.6V. Either use a stable 5V supply, or
use a dedicated reference for the ADC.