How do you get the fractional part of a double?
# mathematics
s
How do you get the fractional part of a double?
g
1. You can try subtracting integer part:
abs(a).let { it - floor(it) }
or
abs(a - truncate(a))
. 2. Well, fractional part is also a reminder of Euclidean division by `1.0`:
abs(a % 1.0)
. UPD. Sorry, I forgot case of negative
a
. Fixed the bug.
s
When I pass in 2.123456789, those functions return 0.12345678900000001. how can I prevent that?
g
You can not because that's how floating point math works. Rounding is included in any definition of fracctional part, so it's unavoidable. But you can: 1. Take closest multiple of 0.1^n for sufficient n. That is equivalent to
truncate(a * 10^n) / 10^n
. 2. Use
BigDecimal
with higher precision. Then you can avoid the rounding via the precision. 3. Convert to string and truncate it manually. (But, of course, no one wants to do this. 🙂 But it's a backup plan.)
Also, to get mathematical fractional part (that returns 0.3 for 1.3 and 0.7 for -1.3) you can use
a - floor(a)
or
a.mod(a)
.
s
But why when I print it out there is no rounding?
Copy code
val x = 2.123456789
println(x)
//2.123456789
g
Because that's how floating point math works. The greater your number is the greater the number's error is. So when you, for example, calculate difference of two very close and very large numbers, the result is small because of their closeness, but an error of the difference is approximate to errors of the minuend and subtrahend, which is relatively large for such small number. For example,
Copy code
println(1_000_000_000.1 - 1_000_000_000.0) // 0.10000002384185791
// But
println(0.1) // 0.1
That's example of a collected error vs no collected error. It also means there is no way to calculate fractional part of a large number with small error using only
double
. Still, see 0.30000000000000004.com (for brief description of the problem), Wikipedia (for full description of the problem), IEEE 754 (for formal description of IEEE 754 standart that is used for
double
type in a lot of modern languages).
s
Thank you so much! I really appreciate the thorough explanation and sources!
289 Views