Używam MPandroidchart, aby wykresować wykres w mojej aplikacji Android. Funkcja "Wejście ()", która zajmuje wartość o osi X i wartości osi Y ma składnię deklaracyjną jako: wpis (float x, float y)

Teraz mój problem z pływakiem w Kotlinie jest następujący:

Otrzymuję dane z innego urządzenia Bluetooth, w którym jednym z pól danych jest wartością znacznika czasu (niepodpisane 32 bitów). Ta wartość znacznika czasu znajduje się w MS, muszę podzielić tę wartość o 1000 i wykreślić wartości osi X w "SEC". Jednak tracę dużo precyzji z typem danych "Float" w Kotlinie.

Na przykład rozważ następujący kod:

/**
* You can edit, run, and share this code. 
* play.kotlinlang.org 
*/

import java.text.DecimalFormat;

fun main() {
   var mArrayList:ArrayList<UByte> = ArrayList()
   mArrayList.add(0xFF.toUByte())
   mArrayList.add(0xFF.toUByte())
   mArrayList.add(0xFF.toUByte())
   mArrayList.add(0xFF.toUByte())


   var intInc:UByte = 0.toUByte()
   var mTimeStamp:UInt 
   var mFloatVal:Float 
   var mDoubleVal:Double 

   for(i in 1..10){
       mArrayList.set(3, intInc)
       intInc = intInc.plus(2.toUByte()).toUByte()

       mTimeStamp = mArrayList.get(0).toUInt().shl(24)
       mTimeStamp = mTimeStamp.or(mArrayList.get(1).toUInt().shl(16))
       mTimeStamp = mTimeStamp.or(mArrayList.get(2).toUInt().shl(8))
       mTimeStamp = mTimeStamp.or(mArrayList.get(3).toUInt().shl(0))

       mDoubleVal = mTimeStamp.toDouble()
       mDoubleVal = mDoubleVal.div(1000)
       mFloatVal = mDoubleVal.toFloat()
       println("mTimeSTamp = $mTimeStamp, mDoubleVal = $mDoubleVal, mFloatVal = $mFloatVal")
   }   
}

Wyjście kodu:

mTimeSTamp = 4294967040, mDoubleVal = 4294967.04, mFloatVal = 4294967.0
mTimeSTamp = 4294967042, mDoubleVal = 4294967.042, mFloatVal = 4294967.0
mTimeSTamp = 4294967044, mDoubleVal = 4294967.044, mFloatVal = 4294967.0
mTimeSTamp = 4294967046, mDoubleVal = 4294967.046, mFloatVal = 4294967.0
mTimeSTamp = 4294967048, mDoubleVal = 4294967.048, mFloatVal = 4294967.0
mTimeSTamp = 4294967050, mDoubleVal = 4294967.05, mFloatVal = 4294967.0
mTimeSTamp = 4294967052, mDoubleVal = 4294967.052, mFloatVal = 4294967.0
mTimeSTamp = 4294967054, mDoubleVal = 4294967.054, mFloatVal = 4294967.0
mTimeSTamp = 4294967056, mDoubleVal = 4294967.056, mFloatVal = 4294967.0
mTimeSTamp = 4294967058, mDoubleVal = 4294967.058, mFloatVal = 4294967.0

Porównując powyżej MDoubleval i Mlashoatval, wydaje się, że istnieje zbyt wiele utraty precyzyjnej danych. Potrzebuję dokładnej wartości pływakowej do 3 miejsc dziesiętnych. Jak mogę to osiągnąć? Rozumiem, że nie możemy dokładnie reprezentować numerów pływających punktów ze względu na ograniczenia w reprezentacji, ale zaskakujące jest, aby zobaczyć to ograniczenie począwszy od pierwszego punktu dziesiętnego.

0
Naresh 11 styczeń 2020, 23:57

1 odpowiedź

Najlepsza odpowiedź

Nie możesz.

Float C / Java / Kotlin jest pojedynczą precyzyjną liczbą pływającym. Dlatego otrzymasz 24 bitów (23 przechowywane bitów Mantissa, a także ukryte wiodące 1) lub około 7 cyfr dziesiętnych precyzji. Gdy używasz więcej cyfr przed dziesiętnym punktem, otrzymasz mniej po przecinku.

1
plugwash 23 marzec 2020, 14:48