Working with float numbers

Hellow Anvil Community
What I’m trying to do:
I’m trying to save and edit a number in a table.

What I’ve tried and what’s not working:
I have a table with a column called “valor”, type number. I have a record with this number: 650048.82. I can see it directly in the table, but when I try to edit the record in question, the number converts to 650048.8199999999. If I change the number just to test it, to 650048.80, editing it doesn’t change it. I’ve tried the same thing several times, but it always changes from 650048.82 to 650048.8199999999. the system I’m creating requires accuracy in the numbers.

Code Sample:

# This is the save method:
        anvil.server.call('guardar_operacion_bancaria',
                          fecha=self.Fecha.date,
                          num_pda=numero_pda,
                          tipo_doc=self.dropTipoDoc.selected_value,
                          correlativo=int(self.txtCorrelativo.text),
                          cuenta=self.dropCuenta_Contable.selected_value,
                          centro=self.dropCentro_Costos.selected_value,
                          sujeto=self.txtSujeto.text,
                          comentario=self.txtComentario.text,
                          valor=round(float(self.txtValor.text), 2), # <-- This line
                          registro_bancario=self.registro_bancario
                        )
 # to edit like this
  def llenar_campos_si_edicion(self):
    if not self.registro_bancario:
      return

    self.txtNumPda.text = self.registro_bancario['NumPda']
    self.Fecha.date = self.registro_bancario['Fecha']
    self.dropTipoDoc.selected_value = self.registro_bancario['Tipo_doc']
    self.txtCorrelativo.text = self.registro_bancario['Correlativo']
    self.dropCentro_Costos.selected_value = self.registro_bancario['centro_costos']
    self.dropCuenta_Contable.selected_value = self.registro_bancario['Cuenta_Contable']
    self.txtSujeto.text = self.registro_bancario['Sujeto']
    self.txtComentario.text = self.registro_bancario['Comentario']
    self.txtValor.text = round(float(self.registro_bancario['Valor']),2) # <--  This line

Gracias!!!

The short answer: the number doesn’t convert from .82 to .8199999999, it is .8199999999 and it is sometimes displayed as .82.

The longer answer you can find it here or here.

1 Like

Also see What Every Programmer Should Know About Floating-Point Arithmetic.

This sort of thing is why Stripe explicitly works in pennies, not dollars. It eliminates the need for fractions altogether.

To follow their solution, your code would convert values to pennies immediately on input, store values in pennies, do arithmetic in pennies, and convert to dollars only for display.

1 Like

Gracias!!, @stefano.menci @p.colbert