Well, the stat formulas are these; you've probably seen them before:
Stat = Math.Floor(Math.Floor((2 * B + I + E) * L / 100 + 5) * N)
And the HP one is different, of course:
Stat = Math.Floor((2 * B + I + E) * L / 100 + L + 10)
Where B = base stat, I = individual value, E = effort value, L = level, and N = nature.
So as you can see, 1) the game does use fractions and decimals when calculating stats, but the final result and the one that you see when you look at the status screen is a rounded number, and it always rounds them down, and 2) EV's are worth 0.25 points at lv. 100. However, it doesn't matter, because B and I will always be whole numbers, so by creatively spreading EV's you can't cause the game to round down to a higher whole number; getting seven EV's in a stat will never give you a higher final stat than getting four in that stat. Also, at lv. 100, if there are no EV's present, then the formula will always produce a whole number, which is why if you want to find an exact IV without adding any EV's, you typically need a lv. 100 pokémon.
Also, the game rounds down further if there is some other modifier placed upon a stat; so, for example, if you're using a choice band, there is no advantage to having 301 attack versus 300 attack, because after multiplying by 1.5x the game will then round either value down to 450. So it is possible in some cases to save an EV here or there if you're looking to add further stat multipliers.