Lee Richardson
Lee Richardson

Reputation: 8837

Converting float to int in F#

Can someone please explain why int (0.4 * 10.0) is 4 yet int ((2.4 - 2.0) * 10.0) is 3?

And then also please explain how to get 4. i.e. Do I really have to do int (System.Math.Round((2.4 - 2.0) * 10.0))?

It's just so ugly for something that should be so simple.

Upvotes: 11

Views: 14482

Answers (5)

katrash
katrash

Reputation: 1165

To covert a float number to an int use:

let i = Convert.ToInt32(f)

Upvotes: 6

Alexey Romanov
Alexey Romanov

Reputation: 170723

Actually, in .Net there is a decimal data type which will help you with this problem, if your numbers can be represented exactly as decimal fractions.

2.4m - 2.0m == 0.4m
2.4 - 2.0   != 0.4

Upvotes: 6

Alexey Romanov
Alexey Romanov

Reputation: 170723

And then also please explain how to get 4. i.e. Do I really have to do

int (System.Math.Round((2.4 - 2.0) * 10.0))

it's just so ugly for something that should be so simple.

Of course not, just define

let round x = int System.Math.Round(x)

Upvotes: 5

Mark Maxham
Mark Maxham

Reputation: 1531

Floating-point numbers are not infinite precision. Some numbers can be represented perfectly (anything involving powers of two, e.g. 1, 1/2 = 0.5, 1/4 = 0.25, etc.), and others can't (e.g. 1/3 cannot be exactly decomposed into a finite sequence of powers of two). Often, chopping the end of the infinite series causes the encoded version of a number to be slightly smaller than its true value.

Combine this with the fact that the (int) operator truncates rather than rounds, and you can run into cases where an operation that should yield 4.0 results in 3.999999999991 instead, which becomes 3.

Any time you're trying to convert floats/doubles to ints, you want to think carefully about which operator you want to use -- truncating (rounding down), rounding up, or rounding-to-nearest.

Since this is an issue with floating-point representations, this is true not just in F#, but C# and (IIRC) Java and other languages.

Upvotes: 1

Pedro Henriques
Pedro Henriques

Reputation: 1736

The double representation of 2.4 - 2.0 is 0.399999999999. When you convert a number to int the decimal part is truncated so 3.999999999 is truncated to 3.

Upvotes: 12

Related Questions