# Learning about doubles

**URL:** <https://forum.xojo.com/t/learning-about-doubles/47997>\
**Category:** Getting Started\
**Created:** [April 3, 2019, 2:30am UTC](https://forum.xojo.com/t/learning-about-doubles/47997 "2019-04-03T02:30:31Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [April 3, 2019, 2:30am UTC](https://forum.xojo.com/t/learning-about-doubles/47997/1 "2019-04-03T02:30:31Z")

</div>

Today I found that:

`Dim i As Integer
i = 5.1 * 100 // result 509`  
I was told that ‘such is the nature of doubles’, in this case 5.1 and 100 are converted to doubles and then casts back to an integer. There are workaround to make sure I get 510, like using Ceil or use single/currency for the operation and then assign to integer.

Then tested:

`Dim i As Integer
i = 5.1 * 10 // result 51
i = 5.1 * 1000 // result 5100`  
so the results are not consistent, I expected 50 and 5099. I guess the number of decimals after the operation change the value enough to alter the final integer/double value.

Then I tested some more and found that:

`Dim i As Integer
i = 5.1 * 10 * 10 // result 510
i = 10 * 10 * 5.1 // result 509`  
and

`Dim i As Double
i = 5.1 * 10 * 10 // 510.
i = 10 * 10 * 5.1 // 509.9999999999999432`

Looking at those results, I have to be careful with doubles.

---

<div class="post-metadata">

**Author:** ![Robert\_Weaver](https://forum.xojo.com/letter_avatar_proxy/v4/letter/r/919ad9/32.png) [@Robert\_Weaver](https://forum.xojo.com/u/Robert_Weaver)\
**Post date:** [April 3, 2019, 2:39am UTC](https://forum.xojo.com/t/learning-about-doubles/47997/2 "2019-04-03T02:39:13Z")

</div>

When converting from any floating point type of number to an integer, the fractional part is truncated. To round the number to the nearest integer, simply add 0.5 to the number before the conversion.

```auto
Dim i As Integer
i = (5.1 * 100) + 0.5 // result 510
```

---

<div class="post-metadata">

**Author:** ![Ivan\_Tellez](https://forum.xojo.com/letter_avatar_proxy/v4/letter/i/a9a28c/32.png) [@Ivan\_Tellez](https://forum.xojo.com/u/Ivan_Tellez)\
**Post date:** [April 3, 2019, 2:39am UTC](https://forum.xojo.com/t/learning-about-doubles/47997/3 "2019-04-03T02:39:25Z")

</div>

> [@431256:@Alberto De Poo](#):
>
> so the results are not consistent, I expected 50 and 5099. I guess the number of decimals after the operation change the value enough to alter the final integer/double value.

[Doubles dont work like that](https://en.wikipedia.org/wiki/Double-precision_floating-point_format)

> [@431256:@Alberto De Poo](#):
>
> Then I tested some more and found that:

Remember operator precedence:

```auto
i = 5.1 * 10 * 10 // result 510
i = 10 * 10 * 5.1 // result 509
```

It is the same as:

```auto
i = 51 * 10 // result 510
i = 100 * 5.1 // result 509
```

> [@431256:@Alberto De Poo](#):
>
> Looking at those results, I have to be careful with doubles.

I try to never use them

---

<div class="post-metadata">

**Author:** ![Jeff\_Tullin](https://forum.xojo.com/user_avatar/forum.xojo.com/jeff_tullin/32/693_2.png) [@Jeff\_Tullin](https://forum.xojo.com/u/Jeff_Tullin)\
**Post date:** [April 3, 2019, 5:34am UTC](https://forum.xojo.com/t/learning-about-doubles/47997/4 "2019-04-03T05:34:19Z")

</div>

> [@](#):
>
> I have to be careful with doubles.

If you then start to use them as integers, certainly…

If you are working with values in the dollars and cents range (eg no more than 2 decimal places) then you should probably work with ‘inflated integers’ where your internal workings are integers 100 times larger than the actual doubles.  
Divide by 100 to display

[code]Dim i As Integer  
i = 51 \* 1000 // result 51000

msgbox "display version : " + str (i \100,“0.00”)[/code] [//510.00](https://510.00)

---

<div class="post-metadata">

**Author:** ![Tim\_Hare](https://forum.xojo.com/user_avatar/forum.xojo.com/tim_hare/32/176_2.png) [@Tim\_Hare](https://forum.xojo.com/u/Tim_Hare)\
**Post date:** [April 3, 2019, 6:50am UTC](https://forum.xojo.com/t/learning-about-doubles/47997/5 "2019-04-03T06:50:26Z")

</div>

If you want an integer result from doubles math, you should round the result.

i = round(100 \* 5.1) // 510

---

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [April 3, 2019, 12:47pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/6 "2019-04-03T12:47:46Z")

</div>

Thank you all for your comments.

Now imagine that you are new to Xojo and programming. That you read the [docs](https://documentation.xojo.com/api/data_types/integer.html) about integer and you think about this:

`Dim i As Integer
i = 5.1`  
what do you expect? i = 5 right? Even without executing the code.

Now, you are presented with the following:

`Dim i As Integer
i = 5.1 * 100`  
what do you expect (without executing the code)?

I could say that I expect that to be 500, why? because I may believe that because I ‘Dim i As Integer’, everything at the right of the equal sign will be treated as integer, so integer of 5.1 = 5 and integer of 100 = 100, 5 \* 100 = 500  
Or I could say that the language will use some numeric datatype that can handle decimals and then convert to integer, getting 510 as a result.  
How should I know that the 5.1 and 100 will be converted to Doubles, and because the nature of the doubles 5.1 will be 5.099999… and i will end as 509 while

`Dim i As Integer
i = 5.11 * 100 // 511`

Now that I know that this is happening, I can make better choices, like using Round, using 10000 then /100 or other option.

I guess what I’m trying to ask, is every operation treated as double and then cast back to the datatype in use? Or just in some cases?  
Example:

`Dim c As Currency
c = 5.1 * 100`

---

<div class="post-metadata">

**Author:** ![Jeff\_Tullin](https://forum.xojo.com/user_avatar/forum.xojo.com/jeff_tullin/32/693_2.png) [@Jeff\_Tullin](https://forum.xojo.com/u/Jeff_Tullin)\
**Post date:** [April 3, 2019, 1:17pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/7 "2019-04-03T13:17:07Z")

</div>

[quote]Dim i As Integer  
i = 5.1 \* 100  
what do you expect (without executing the code)?[/quote]

510

Nobody would expect 509 without running the code  
I can rationalise why it happens, but only in hindsight.

And it does expose the problem of double compares, which are always dangerous;

ie if 5.1 \* 100 = 510 then

---

<div class="post-metadata">

**Author:** ![Emile\_Schwarz](https://forum.xojo.com/letter_avatar_proxy/v4/letter/e/90ced4/32.png) [@Emile\_Schwarz](https://forum.xojo.com/u/Emile_Schwarz)\
**Post date:** [April 3, 2019, 2:44pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/8 "2019-04-03T14:44:59Z")

</div>

After reading the entries above, I was thinking:

` Dim i As Integer
  i = (5.1 * 100)`

so 5.1 \* 100 will be evaluated, then the result stored into i.

No, it was not the case. For some reason, `5.1` is evaluated (resized to `integer`) and then `* 100` and the result is stored into `i`.

The question is: is this the right way to do the things (I suppose so, else Xojo engineer(s) would wrote Xojo differently).

Conclusion: an additional entry in the LR is required (even if this is learned in the CSI studies).

A simple compare with how Encodings works with strings let me think  
a String without encoding is UTF8 by default. (Read String in the LR).

So, before making math on data, Xojo reads the datatype of the variable who will hold the value and work accordingly (set the formula to/as Integer and resolve it).

What as developers must we do ?  
We have to know how Xojo (the development language) works and code accordingly to what we want: do we want an accurate result (with the decimal part) ?  
Use the correct Datatype declared variable (a Double or an Integer or).

Remember: `Floor` and `Ceil` are here for something. What if you are programming a Billing software (accounting software) ?

---

<div class="post-metadata">

**Author:** ![DaveS](https://forum.xojo.com/letter_avatar_proxy/v4/letter/d/848f3c/32.png) [@DaveS](https://forum.xojo.com/u/DaveS)\
**Post date:** [April 3, 2019, 3:02pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/9 "2019-04-03T15:02:01Z")

</div>

I was a little bit skeptical that something as mundane as “5.1” would cause such an issue. So of course I replicated the example in Xojo as saw the same 509 as everyone else did.

So as an experiment, I did it in Swift to see what IT did.

```auto
var i : Int = Int(5.1*100)
print("I=\\(i)")
```

basically the only difference is having to add the CAST, as SWIFT if very strict with datatypes… but that not withstanding… it still came out 509 … and by default Swift uses a 64bit Double

---

<div class="post-metadata">

**Author:** ![Rick\_Araujo](https://forum.xojo.com/user_avatar/forum.xojo.com/rick_araujo/32/251_2.png) [@Rick\_Araujo](https://forum.xojo.com/u/Rick_Araujo)\
**Post date:** [April 3, 2019, 3:22pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/10 "2019-04-03T15:22:51Z")

</div>

5.1 \* 100 is a 509.9999999999999432 Double. Unhappily casting it to an integer does a Trunc() instead of a Round(), so, that’s why the 509. Use manually a Round() to achieve the expected result.

Dim i As Integer = round(5.1 \* 100)

Dim d As Double = 5.1 \* 100  
Dim j As Integer = Round(d)

---

<div class="post-metadata">

**Author:** ![Rick\_Araujo](https://forum.xojo.com/user_avatar/forum.xojo.com/rick_araujo/32/251_2.png) [@Rick\_Araujo](https://forum.xojo.com/u/Rick_Araujo)\
**Post date:** [April 3, 2019, 3:26pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/11 "2019-04-03T15:26:57Z")

</div>

But, interestingly, what do you expect as a result for Round(-5.1\*100)? That’s why I made my own “round()” for my Money Class.

---

<div class="post-metadata">

**Author:** ![Rick\_Araujo](https://forum.xojo.com/user_avatar/forum.xojo.com/rick_araujo/32/251_2.png) [@Rick\_Araujo](https://forum.xojo.com/u/Rick_Araujo)\
**Post date:** [April 3, 2019, 3:43pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/12 "2019-04-03T15:43:31Z")

</div>

`Function RoundInt(d As Double) As Integer
  // Rounds the value to the upper nearest positive integer or lower nearest larger negative
  If d<B Then Return -Round(Abs(d)) 
  Return Round(d)
End Function`

---

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [April 3, 2019, 3:50pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/13 "2019-04-03T15:50:02Z")

</div>

Thank you again.

So this means that every operation Xojo does is with doubles and then cast back to the corresponding datatype?

For example:

`Dim c As Currency
c = 5.1 * 100`  
5.1 \* 100 is evaluated as double then when it is assigned to ‘c’ Xojo does some ‘fixing’/‘rounding’ so I get 510?

or with single:

`Dim s As Single
s = 5.1 * 100`

---

<div class="post-metadata">

**Author:** ![Rick\_Araujo](https://forum.xojo.com/user_avatar/forum.xojo.com/rick_araujo/32/251_2.png) [@Rick\_Araujo](https://forum.xojo.com/u/Rick_Araujo)\
**Post date:** [April 3, 2019, 4:04pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/14 "2019-04-03T16:04:07Z")

</div>

> [@431306:@Alberto De Poo](#):
>
> this means that every operation Xojo does is with doubles and then cast back to the corresponding datatype?

The exact answer for this, only the compiler team (@Joe Ranieri ?) could answer precisely, but it would be a simpler way of doing things when the compiler noticed floating point arithmetic involved, promote all to Double, do the magic, cast the result back to the final form.

---

<div class="post-metadata">

**Author:** ![Stéphane\_Mons](https://forum.xojo.com/letter_avatar_proxy/v4/letter/s/f07891/32.png) [@Stéphane\_Mons](https://forum.xojo.com/u/St%C3%A9phane_Mons)\
**Post date:** [April 3, 2019, 4:08pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/15 "2019-04-03T16:08:32Z")

</div>

@Alberto De Poo  Or, instead of using a mixture of doubles, singles and integers in the same formula, you also can explicitly tell the compiler what you want. For example, you can use 100.0 instead of 100.

---

<div class="post-metadata">

**Author:** ![Rick\_Araujo](https://forum.xojo.com/user_avatar/forum.xojo.com/rick_araujo/32/251_2.png) [@Rick\_Araujo](https://forum.xojo.com/u/Rick_Araujo)\
**Post date:** [April 3, 2019, 4:13pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/16 "2019-04-03T16:13:59Z")

</div>

The compiler needs to automagically promote a 100 to a 100.0 when the expression contains floating parts.

---

<div class="post-metadata">

**Author:** ![Rick\_Araujo](https://forum.xojo.com/user_avatar/forum.xojo.com/rick_araujo/32/251_2.png) [@Rick\_Araujo](https://forum.xojo.com/u/Rick_Araujo)\
**Post date:** [April 3, 2019, 4:20pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/17 "2019-04-03T16:20:09Z")

</div>

It needs to obey some direct castings like:

`Dim i As Integer = Integer(509.99)-9`.  
There’s a float, but as it’s final form would be Integer, the rest of the simple math should be int math, not floating math.

---

<div class="post-metadata">

**Author:** ![Tim\_Hare](https://forum.xojo.com/user_avatar/forum.xojo.com/tim_hare/32/176_2.png) [@Tim\_Hare](https://forum.xojo.com/u/Tim_Hare)\
**Post date:** [April 4, 2019, 1:04am UTC](https://forum.xojo.com/t/learning-about-doubles/47997/18 "2019-04-04T01:04:08Z")

</div>

Xojo evaluates the data types on the right hand side of the equals sign (the data type of the receiving variable is not taken into consideration) and promotes all data to the type that most closely accommodates them all. Then it performs the operation.

dim i as integer

i = 5.1 \* 100  
integer = double \* integer  
integer = double \* double  
integer = double (truncated)

i = 5 \* 100  
integer = integer \* integer  
integer = integer (direct assignment)

As far as the original issue of getting a value of 509, it is not unique to Xojo. It is a result of how doubles are represented and is a problem in all programming languages. That is why you never represent monetary values as a double in an accounting application. You will be off by fractions of cents in your calculations.

On the other hand, doubles are completely precise for integer values and were used for holding integers greater than 32 bits before 64-bit variables became prevalent. A double gives you a precise 53-bit integer value.

---

<div class="post-metadata">

**Author:** ![Jürg\_Otter](https://forum.xojo.com/user_avatar/forum.xojo.com/j%C3%BCrg_otter/32/584_2.png) [@Jürg\_Otter](https://forum.xojo.com/u/J%C3%BCrg_Otter)\
**Post date:** [April 4, 2019, 8:29pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/19 "2019-04-04T20:29:36Z")

</div>

If you’re interested in learning more about why some decimal numbers dont have their exact floating point representation…  
…then this is a good read: [Bartosz Ciechanowski: Exposing Floating Point](https://ciechanow.ski/exposing-floating-point/)

---

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [April 4, 2019, 10:08pm UTC](https://forum.xojo.com/t/learning-about-doubles/47997/20 "2019-04-04T22:08:27Z")

</div>

Does `Str(double)` round the number, use Ceil or is doing something else?

`Dim d As Double
d = 5.1 * 100 // 509.9999999999999432
MsgBox Str(d) // 510`

[Next page](https://forum.xojo.com/t/learning-about-doubles/47997.md?page=2)
