Jak przekonwertować float na tablicę bajtów o długości 4 (tablica znaków *)? Muszę przesłać sieci niektóre dane, tcp i trzeba wysłać float jako tablicę bajtów. (Znam dokładność do dwóch cyfr dziesiętnych, więc w tej chwili po stronie klienta pomnożę przez 100, a na serwerze dzielę przez 100 - po prostu przelicz na liczbę całkowitą, a następnie znajdź bajty przy pomocy operacji & 0xff < <). Ale jest brzydka i może stracić precyzję w czasie.Jak przekonwertować float na tablicę bajtów o długości 4 (tablica znaków *)?
Odpowiedz
Reading dowolny typu jako sekwencja bajtów jest całkiem prosta:
float f = 0.5f;
unsigned char const * p = reinterpret_cast<unsigned char const *>(&f);
for (std::size_t i = 0; i != sizeof(float); ++i)
{
std::printf("The byte #%zu is 0x%02X\n", i, p[i]);
}
Pisanie do pacy ze strumienia sieciowego działa podobnie, tylko chcesz pominąć const
.
Jest zawsze dozwolone zinterpretować dowolny obiekt jako sekwencja bajtów (dowolny char
Typ jest dopuszczalna), co wyraźnie nie Naruszenie aliasingu. Zauważ, że reprezentacja binarna dowolnego typu jest oczywiście zależna od platformy, więc powinieneś używać tego tylko do serializacji, jeśli odbiorca ma tę samą platformę.
Ale to oczywiście nie pomoże mu, jeśli ma pisać bajty do sieci. –
@JamesKanze: Oczywiście, możesz użyć 'write (fd, p, sizeof (float))' ... pytanie brzmi: kto może * przeczytać *, że :-) –
Nie ma praktycznie żadnego przypadku, w którym 'write' byłby poprawny. Ale pytanie dotyczyło wyjścia przez sieć. To, co pisze, musi odpowiadać formatowi, który zdefiniował protokół, którego używa. –
Pierwszą rzeczą, którą musisz zrobić, to określić format float w protokole sieciowym. Wystarczy wiedzieć, że to 4 bajty niewiele ci mówią: IBM mainframe, Oracle Sparc i zwykły komputer PC mają cztery bajty, ale mają trzy różne formaty . Gdy wiesz, format, w zależności od jego wymagań i swoich przenośności, mogą być stosowane dwie różne strategie:
Jeśli format jest w protokole IEEE (najczęstszy przypadek), i nie muszą być przenośne na maszynach, które nie są IEEE (większość Unix Windows i są IEEE — większość dużych komputerów nie są), następnie można użyć typu paronomazja przekonwertować pływaka do uint32_t
i wyjście, które, przy użyciu:
std::ostream&
output32BitUInt(std::ostream& dest, uint32_t value)
{
dest.put((value >> 24) & 0xFF);
dest.put((value >> 16) & 0xFF);
dest.put((value >> 8) & 0xFF);
dest.put((value ) & 0xFF);
}
dla big-endian (zwykła kolejność sieci) lub:
std::ostream&
output32BitUInt(std::ostream& dest, uint32_t value)
{
dest.put((value ) & 0xFF);
dest.put((value >> 8) & 0xFF);
dest.put((value >> 16) & 0xFF);
dest.put((value >> 24) & 0xFF);
}
dla little-endian (używane przez niektóre protokoły). Który z nich użyjesz, zależy od formatu zdefiniowanego dla protokołu.
Aby przekonwertować z float
na uint32_t
, należy sprawdzić kompilator . Używanie memcpy
jest jedyną metodą, która jest w pełni gwarantowana przez standard memcpy
; intencją jest to, że używając a reinterpret_cast<uint32_t&>
również w pracy z float, i kompilator większość (wszystkie?) obsługuje również użycie union
.
Jeśli trzeba być przenośne na mainframe, jak również, czy format jest coś innego niż IEEE Pokochasz trzeba wyodrębnić wykładnik, podpisać i mantysa z pływaka, a wyjście każdy w formatu docelowego .Coś jak poniżej powinny pracować wyjściowego IEEE grubokońcej na każdą maszynę (łącznie mainframe które nie korzystają IEEE) i powinien dać pewne wyobrażenie:
oxdrstream&
oxdrstream::operator<<(
float source)
{
BytePutter dest(*this) ;
bool isNeg = source < 0 ;
if (isNeg) {
source = - source ;
}
int exp ;
if (source == 0.0) {
exp = 0 ;
} else {
source = ldexp(frexp(source, &exp), 24) ;
exp += 126 ;
}
uint32_t mant = source ;
dest.put((isNeg ? 0x80 : 0x00) | exp >> 1) ;
dest.put(((exp << 7) & 0x80) | ((mant >> 16) & 0x7F)) ;
dest.put(mant >> 8) ;
dest.put(mant ) ;
return *this ;
}
(BytePutter
to prosta klasa który zajmuje się standardową płytką standardową i sprawdza błędy.) Oczywiście, różne manipulacje dla wyjścia będą różne, jeśli wyjściowy format nie jest IEEE, ale powinno to pokazać podstawowe zasady. (Jeśli potrzeba przenoszenia do jednych z bardziej egzotycznych mainframe, które nie obsługują uint32_t
, można zastąpić go dowolnym unsigned integralną typu, który jest większy niż 23 bity).
Wystarczy nałożyć dane w jednym obszar, w C
union dataUnion {
float f;
char fBuff[sizeof(float)];
}
// to use:
dataUnion myUnion;
//
myUnion.f = 3.24;
for(int i=0;i<sizeof(float);i++)
fputc(myUnion.fbuff[i],fp); // or what ever stream output....
- 1. Tablica bajtów do float
- 2. Jak przekonwertować 4 bajty na Swift float?
- 3. Jak przekonwertować tablicę znaków na tablicę znaków?
- 4. Jak przekonwertować tablicę bajtów na obiekt blobowy
- 5. Jak przekonwertować ciąg znaków UTF8 na tablicę bajtów?
- 6. Jak przekonwertować tablicę ciągów na tablicę bajtów? (java)
- 7. Jak przekonwertować float na 4-bajtowe znaki w C?
- 8. Jak przekonwertować tablicę bajtów na załącznik mailowy
- 9. Jak przekonwertować tablicę bajtów na Bitmapę
- 10. Android: jak przekonwertować tablicę bajtów na Bitmapę?
- 11. Jak przekonwertować outputStream na tablicę bajtów?
- 12. Jak przekonwertować tablicę bajtów na MultipartFile
- 13. Jak przekonwertować łańcuch szesnastkowy na tablicę bajtów?
- 14. Jak przekonwertować tablicę bajtów Stream
- 15. F #: Konwertowanie ciągu znaków na tablicę bajtów
- 16. Tablica bajtów Androida na Bitmapie Jak
- 17. Jak przekonwertować Char na Float
- 18. Jak przekonwertować ciąg na float w mysql?
- 19. C# Jak przekonwertować System.Net.ConnectStream na bajt [] (tablica)
- 20. Jak przekonwertować tablicę bajtów UInt8 na ciąg w Swift
- 21. Jak przekonwertować liczbę całkowitą na tablicę bajtów w php
- 22. Jak utworzyć float z dwóch bajtów?
- 23. Jak przekonwertować ciąg znaków szesnastkowy na ciąg bajtów w Perlu?
- 24. bajt [] tablica do struct z tablicą o zmiennej długości
- 25. Jak przekonwertować tablicę bajtów do pliku ZIP
- 26. Tablica bajtów do NSData
- 27. Jak przekonwertować tablicę numpy z 'float64' na 'float'
- 28. mssql przekonwertować varchar na float
- 29. pythonowa tablica liczb o dowolnych długościach znaków
- 30. Jak przekonwertować liczbę całkowitą na tablicę czterech bajtów w pythonie
Myślę, że potrzebujesz 8 bajtów, aby zachować precyzję. –
@HennoBrandsma To ogólnie "podwójne". W większości nowoczesnych systemów 'float' to 4-bajtowy format IEEE-754. –
Nie dyskontuj księgowości endian w ostatecznym rozwiązaniu, chyba że ograniczasz swój klient/serwer do jednego formatu (dużego lub małego). – WhozCraig