Skip to main content
iVentureTeam

float

Every decimal number in Odoo passes through the float widget. Its option panel hides a naming trap, and since 19.0 the input quietly evaluates math. Here is the full, source-verified picture.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 18, 2026Updated August 18, 20267 min read
Odoo 19 form view showing decimal fields rendered by the float widget with localized thousand separators and configured digit precision.
Studio nameDecimal
Technical namefloat
Field typesfloat, monetary
Viewsform, list, kanban (default widget for float fields everywhere)
Moduleweb, present in every Odoo database
Used in core7 explicit occurrences across hr_holidays, project, crm; implicitly it renders every float field in every database
VersionsOdoo 20.0, Odoo 19.0, Odoo 18.0, Odoo 17.0, Odoo 16.0
No-code setupYes: Studio's Decimal field uses this widget by default
Alternativesmonetary, percentage, float_time, progressbar

What the Float field does

Quantities, hours, percentages stored as numbers, weights, coefficients: any field declared as fields.Float renders through this widget unless the view says otherwise. It formats the stored value with your language's thousand separators and decimal point, applies a digit precision, and parses whatever the user types back into a float.

Because it is the default, you rarely write widget="float" yourself; the 7 explicit usages in core are views that need one of its options. What you configure instead are the options, and two of them do more than the labels suggest: the input accepts full math expressions, and the precision system has two competing sources with a defined winner.

Since 19.0 the widget also accepts monetary fields, giving you a currency-less rendering of an amount when the currency symbol would be noise.

What this means for your team

Number formatting sounds cosmetic until an operations report shows 12,5 to a US manager and 12.5 to a German one, or until a purchasing team rounds a unit cost that the database stores to five decimals. The float widget is where Odoo decides what people see, which is not always what is stored: display precision comes from the widget's digits configuration, storage precision from the field definition. Most "Odoo rounds my numbers wrong" complaints are a mismatch between those two layers, not a calculation bug.

The 19.0 math input is a real productivity feature for data entry teams: typing =1250/4 into a quantity, or +=50 onto an existing stock count, beats reaching for a calculator. It is also worth telling your users it exists, because nobody discovers *= on their own.

When a number needs to read at a glance rather than exactly, human_readable turns 500,000,000 into 500M, which is usually the right call on dashboards and the wrong one on anything an accountant reconciles.

Setting it up in Odoo Studio (no code)

Odoo Studio (Enterprise) covers the standard case without code.

  1. Open the form or list you want to change and click Studio.

  2. From the Add tab, drag a Decimal field onto the view. The float widget is its default rendering; there is nothing to select.

  3. In Properties, set the label and standard properties. Studio notes that decimals display with two digits by default while the database stores more.

  4. If the number is really a percentage, a progress value or a time, switch the Widget dropdown to Percentage, Progress Bar or Time instead.

What Studio cannot do here

Studio stops at placing the field. The widget's formatting controls, digits, min_display_digits, hide_trailing_zeros, human_readable with decimals, and step, are all XML-level options with no Studio toggle. Changing display precision per view, or making a form input step by 0.25, is a one-line view change for a developer and not available otherwise. Decimal storage precision is a different layer again: it belongs to the field definition and decimal precision settings, not to this widget.

Supported options in Odoo 19

Verified against float_field.js in the Odoo 19.0 web module, including its extractProps, which is where this widget's biggest surprise lives.

OptionTypeWhat it does
digitsarray [width, decimals]Display precision, e.g. [16, 3] for three decimals. Also accepted as a digits attribute on the field element; the attribute takes precedence over the option.
min_display_digitsnumberMinimum digits kept when formatting. Declared in the options panel as minDigits, but extractProps reads only this snake_case name; the declared name is ignored.
enable_formattingbooleanSet false to bypass locale formatting entirely: no thousand separators, no digit padding, raw value in and out.(default: true)
hide_trailing_zerosbooleanTrims zeros right of the last significant decimal, so 1.20 renders 1.2. Pairs well with min_display_digits.(since Odoo 19.0)
human_readablebooleanCompact display for large numbers (500,000,000,000 renders as 500G). The exact value returns while the input has focus.
decimalsnumberDecimal places used by the compact human_readable format only; ignored without it.(default: 0)
typestringSet to "number" for a native HTML number input. Disables locale formatting while editing and the =expression math input.(default: text)
stepnumberSpinner increment for the native input; only meaningful together with type: "number".

The minimum-digits option is broken as declared. The options panel metadata declares minDigits, but extractProps only reads options.min_display_digits. Write min_display_digits in your XML; the declared camelCase name is silently ignored. The same file also shows digits accepted from two places, and the source comments call this out as historical debt: when both the digits attribute and the digits option are present, the attribute wins.

Working examples

Display precision

<field name="efficiency_ratio" digits="[16, 3]"/>

Three decimals on screen regardless of what the field stores. The same value can be passed as options="{'digits': [16, 3]}"; if both are present the attribute wins.

Clean numbers without zero padding

<field name="weight"
       options="{'hide_trailing_zeros': True, 'min_display_digits': 2}"/>

1.20 renders as 1.2, while min_display_digits keeps at least two digits of significance. Note the snake_case name; the declared minDigits does nothing.

Dashboard-friendly large numbers

<field name="total_volume"
       options="{'human_readable': True, 'decimals': 1}"/>

500,000,000 becomes 500.0M while the field keeps focus-in editing of the exact value. decimals only applies together with human_readable.

Native number input with stepping

<field name="hours"
       options="{'type': 'number', 'step': 0.25}"/>

Renders an HTML number input whose spinner moves in quarter steps. In this mode locale formatting is bypassed while editing, and the math-expression parsing below does not apply.

The input is a calculator since Odoo 19

Since 19.0 the default text input does not just parse numbers, it parses arithmetic. Two distinct mechanisms are in the source.

Expressions with a leading equals sign. Typing =8*4+2 evaluates the expression and stores 34. The parser converts ^ to exponentiation and evaluates through Odoo's safe expression evaluator, not JavaScript's eval.

Relative operations, new in 19.0. Typing an operator followed by equals and a number, +=10, -=5, *=2 or /=4, applies that operation to the current value of the field. The pattern is strict: operator first, then =, then one number. This is the mechanism enabled by the allowOperation flag the float widget passes to its parser, and it is easy to demonstrate on any quantity field in 19.

Both are display-layer features of the standard text mode. Set type: 'number' and you trade them for the browser's native input. One removal to know about: 18.0 forwarded the placeholder attribute to the input, and 19.0 dropped that prop from the widget entirely, so a placeholder on a plain float field no longer renders.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. Options and behavior unchanged in the development branch; internals rewritten. See below.
Odoo 19.0VerifiedAdds hide_trailing_zeros, monetary type support and relative math input; drops the placeholder attribute. Verified against the shipped source.
Odoo 18.0VerifiedSame core options minus hide_trailing_zeros; float type only; placeholder attribute still rendered.
Odoo 17.0VerifiedWidget present with the same registration; option set close to 18.0.
Odoo 16.0VerifiedWidget present; registered directly as a component class in the pre-descriptor style, without options panel metadata.

Upgrade note for 18 to 19. Three changes matter: placeholder attributes on float fields stop rendering, the widget starts accepting monetary fields, and empty-value detection changed from "never empty" to a false-check, which affects list-view empty-cell styling. Option names you already use carry over unchanged.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. The notes below read the public development branch, which is unstable until release; we re-verify against the shipped version.

For the float widget the development branch shows no functional change: the option list, extractProps, supported types and registration are all identical to 19.0, and the minDigits versus min_display_digits mismatch is still there. What does change is the component's internals, rewritten onto the new Owl signals and props system (useProps, proxy, signal.ref), so JavaScript patches against FloatField will need review even though views carry over untouched.

Common problems and fixes

SymptomCause and fix
min_display_digits seems to do nothingIt was written as minDigits, the name the options panel declares but the code never reads. Use min_display_digits in the options dict.
Digits option ignoredA digits attribute is also set on the field element, and the attribute wins. Keep one source of precision; prefer the attribute or remove it.
The displayed value differs from exports and computationsWidget digits control display only; the database stores the field's full precision. Align the field's decimal precision setting with the display, or accept the difference knowingly.
Placeholder text no longer appears after upgrading to 19The float widget dropped its placeholder prop in 19.0. No widget-level fix; use a help tooltip, a default value, or a custom widget if the hint is essential.
Typing =5*3 stores the formula literallyThe field uses type: "number", whose native input bypasses Odoo's expression parser. Remove the type option to return to the text-based input.
Large numbers show as 500G and users want exact figureshuman_readable is enabled on the view. Remove the option, or keep it and train users that focusing the field reveals the exact value.

Float field vs the alternatives

WidgetBest forKey difference
floatPlain decimal numbers without a display unitLocale-aware formatting plus math-expression input, no unit semantics
monetaryAmounts tied to a currencyRenders the currency symbol and uses currency decimal rules
percentageFractions shown as percentDisplays 0.15 as 15% and converts on input
float_timeDurations stored as float hoursFormats 1.5 as 01:30 and parses HH:MM input
progressbarProgress toward a max valueGraphical bar rather than an editable number

The practical test: if the number carries a unit in the user's head, hours, percent, money, pick the widget for that unit. Reach for the plain float only when the number is just a number.

Frequently asked questions

How do I control decimals on a float field in Odoo?+
Display decimals come from the widget: set digits="[16, 2]" as an attribute or options="{'digits': [16, 2]}"; the attribute wins if both exist. Storage decimals come from the field definition and, for many business fields, the Decimal Accuracy settings. The two layers are independent, which is the root of most rounding confusion.
Why does min_display_digits work but minDigits does not?+
The widget's options metadata declares the name minDigits, but the code that reads XML options (extractProps) only looks for options.min_display_digits. We verified this in the 19.0 source, and the mismatch is still present on the Odoo 20 development branch.
Can users type math into Odoo number fields?+
Yes, in the standard text mode. =8*4 evaluates to 32 on confirm, and since 19.0 relative operations like +=10, -=5, *=2 and /=4 apply to the current value. Fields configured with type: 'number' use the browser's native input and skip this parsing.
How do I stop Odoo showing trailing zeros like 1.20?+
Add options="{'hide_trailing_zeros': True}", available since 19.0. Combine with min_display_digits if you still want a minimum number of significant digits.
Does the float widget work on monetary fields?+
Since 19.0, yes. It renders the amount without a currency symbol, which is occasionally what a dense list view needs. For normal amounts use the monetary widget, which handles the currency and its decimal rules.
Why is there no placeholder on my float field in Odoo 19?+
Support for the placeholder attribute was removed from this widget in 19.0; 18.0 still rendered it. If the hint matters, use a help tooltip or a default value instead.
What is human_readable for?+
Compact display of large numbers: 500,000,000 renders as 500M, with decimals controlling the compact format's precision. Focusing the input shows the exact value for editing. Use it on dashboards, avoid it on anything that gets reconciled.

Numbers displaying one way and storing another?

Precision mismatches between screens, reports and exports erode trust in an ERP fast. We audit decimal accuracy end to end, from field definitions to view options, and fix the layer that is actually wrong, on Odoo 16 through 19.

Book a free consultation

How this page was produced

The option table was read from float_field.js in the Odoo 19.0 web module, including the extractProps path that exposes the min_display_digits naming mismatch, and the parser source (parsers.js) for the expression and relative-operation input. Formatting behavior was confirmed on a clean Odoo 19 database. Version differences come from diffing the same files on 16.0, 17.0, 18.0 and master. The Odoo 20 section reads the unreleased development branch and is marked as such. Corrections are welcome via our contact page.