1
    @Test
    fun float_test() {
        val float = 1.123451234512345F

        val expected = "1.123451234512345"
        val actual   = float.toString() //actual comes 1.1234512

        assertThat(actual).isEqualTo(expected) //failed
    }

when i convert float 1.123451234512345F to String only 1.1234512 comes as a result

is there any reason of this ?..

J.ty
  • 337
  • 1
  • 3
  • 18
  • 6
    Hint: what do you think the precision of `float` is? How many significant digits do you expect it to be able to store, and why? – Jon Skeet Jan 03 '20 at 07:07
  • 2
    https://kotlinlang.org/docs/reference/basic-types.html – Jon Skeet Jan 03 '20 at 07:07
  • Please refer to this link **for java** [https://stackoverflow.com/questions/7552660/java-convert-float-to-string-and-string-to-float](https://stackoverflow.com/questions/7552660/java-convert-float-to-string-and-string-to-float) – Mandar Dharurkar Jan 03 '20 at 07:09

3 Answers3

2

Is there any reason of this ?

Your literal 1.123451234512345 has 15 decimal digits of precision1.

A float can only represent 6 to 7 digits of precision. Further digits are lost when the number is converted to a float by the compiler.

Possible solution: use double rather than float.


1 - Actually, your literal is 1.123451234512345F. The F suffix means that the literal value is a float, and hence the precision is lost when the literal value is computed. For a double literal, leave off the F or replace it with D.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • There is no `D` in Kotlin. `Double`s are identified by the decimal dot and the absence of the `F`. E.g. `1.1` vs `1.1F` – gpunto Jan 05 '20 at 11:20
0

If you want to preserve all digits, the type to use is BigDecimal:

val float = BigDecimal("1.123451234512345")

Note that you can use the normal operators + etc. on BigDecimals in Kotlin, unlike in Java.

toString on Float (and Double) is defined to only return enough digits to distinguish from any other value of the same type:

How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type float. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument f. Then f must be the float value nearest to x; or, if two float values are equally close to x, then f must be one of them and the least significant bit of the significand of f must be 0.

(the link is to Java documentation, but it applies for Kotlin as well)

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
-1

according to documentation

For floating-point numbers, Kotlin provides types Float and Double. According to the IEEE 754 standard, floating point types differ by their decimal place, that is, how many decimal digits they can store. Float reflects the IEEE 754 single precision, while Double provides double precision.

+--------+------------+------------------+---------------+----------------+
|  Type  | Size(bits) | Significant bits | Exponent bits | Decimal digits |
+--------+------------+------------------+---------------+----------------+
| Float  |     32     |        24        |       8       |      6-7       |
| Double |     64     |        53        |      11       |     15-16      |
+--------+------------+------------------+---------------+----------------+

and there is

If such a value contains more than 6-7 decimal digits, it will be rounded.

therefore for a float number we have :

val eFloat = 2.7182818284f // Float, actual value is 2.7182817
Mojtaba Haddadi
  • 1,346
  • 16
  • 26
  • The number of decimal digits has little or nothing to do with the number of decimal places. The Kotlin document is wrong about this, and attributes to IEE-754 statements which are not in there. – user207421 Jan 03 '20 at 08:52
  • @user207421 :i don't understand , you mean kotlin violates the `IEEE 754` or this number `val eFloat = 2.7182818284f` changes to something else ? – Mojtaba Haddadi Jan 03 '20 at 09:06
  • 1
    @MojtabaHaddadi The actual value is not 2.7182817, which can't be represented by a finite binary fraction. – Alexey Romanov Jan 03 '20 at 09:39