https://github.com/odoo/odoo/blob/b192431aeecc59b48898ce9c6f276b82d65cbfa6/addons/stock/models/stock_move.py#L1026

rounding_method ='UP'
I think it **need be changed to:**
rounding_method ='HALF-UP'

I get this message then I Verify new Delivery(stock.picking):

> The initial demand has been updated.
> My Product
> Quantity : 5.951 -> 5.949999999999999 

and
> The initial demand has been updated.
> My Product
> Quantity : 5.951 -> 5.951 


How I did it(you can also repeat this error): Create new Product > add Qty on hand > Create SO > Add Product with quantity 5.5 > Verify > open Delivery > add Delivered qty 5.95 > Verify > Get trouble: odoo change my qty to 5.951
![default](https://user-images.githubusercontent.com/34191760/39213952-9b246470-481b-11e8-8e06-a074b1044536.png)

You can try execute in python:
5.95 - 5.5 = 0.4500000000000002

Look at the code:
```
            extra_move_quantity = float_round(
                self.quantity_done - self.product_uom_qty,
                precision_rounding=self.product_uom.rounding,
                rounding_method ='UP')
```
if you setup parameters like this:
```
            0.451 = float_round(
                5.95 - 5.5,
                precision_rounding=self.product_uom.rounding,
                rounding_method ='UP')
```
Then you get 0.451.  This is wrong!
Try:
```
            0.45 = float_round(
                5.95 - 5.5,
                precision_rounding=self.product_uom.rounding,
                rounding_method ='HALF-UP')
```
0.45 = 5.95 - 5.5
addons/stock/models/stock_move.py
for move in void_moves:
            move.string_availability_info = ''  
        for move in other_moves:
            total_available = min(move.product_qty, move.reserved_availability + move.availability)
            total_available = move.product_id.uom_id._compute_quantity(total_available, move.product_uom, round=False)
            total_available = float_round(total_available, precision_digits=precision)
            info = str(total_available)
            if self.user_has_groups('product.group_uom'):
                info += ' ' + move.product_uom.name
            if move.reserved_availability:
                if move.reserved_availability != total_available:
                    
                    reserved_available = move.product_id.uom_id._compute_quantity(move.reserved_availability, move.product_uom, round=False)
                    reserved_available = float_round(reserved_available, precision_digits=precision)
                    info += _(' (%s reserved)') % str(reserved_available)
                else:
                    
                    info += _(' (reserved)')
            move.string_availability_info = info
    @api.constrains('product_uom')
    def _check_uom(self):
        moves_error = self.filtered(lambda move: move.product_id.uom_id.category_id != move.product_uom.category_id)
        if moves_error:
            user_warning = _('You try to move a product using a UoM that is not compatible with the UoM of the product moved. Please use an UoM in the same UoM category.')
            for move in moves_error:
                user_warning += _('\n\n%s --> Product UoM is %s (%s) - Move UoM is %s (%s)') % (move.product_id.display_name, move.product_id.uom_id.name, move.product_id.uom_id.category_id.name, move.product_uom.name, move.product_uom.category_id.name)
            user_warning += _('\n\nBlocking: %s') % ' ,'.join(moves_error.mapped('name'))
            raise UserError(user_warning)
    @api.model_cr
    def init(self):