Jenis floating point ukuran tetap

92

Pada header stdint.h(C99), boost / cstdint.hpp , dan cstdint(C ++ 0x) terdapat, antara lain, tipenya int32_t.

Apakah ada tipe floating point ukuran tetap yang serupa? Sesuatu seperti float32_t?

Pietro
sumber
4
Mengapa Anda membutuhkan sesuatu seperti itu?
AraK
41
Anda memerlukan sesuatu seperti itu ketika Anda memiliki struktur data dengan nilai floating-point dan Anda juga ingin tahu persis apa ukurannya.
mafia
5
@mobrule: Jika Anda hanya ingin tahu apa ukurannya, Anda menggunakan sizeofoperator. Jenis seperti ini akan berguna saat algoritme mengharuskan ukuran spesifiknya diketahui.
Stephen Canon
6
@ Stephen Canon - ya, untuk saat Anda ingin menjamin berapa ukurannya. Katakanlah, bahwa sebuah instance dari struktur data Anda akan muat dalam 64 bit dan dapat diteruskan dengan nilai ke beberapa perpustakaan eksternal.
mafia
7
@StephenCanon Pertimbangkan perpustakaan serialisasi lintas platform. Bagaimana dapat sizeofdigunakan untuk mengatasi masalah jenis mengambang yang menyusun dan tidak menyusun secara konsisten?
Kyle Strand

Jawaban:

48

Tidak ada yang seperti ini dalam standar C atau C ++ saat ini. Faktanya, bahkan tidak ada jaminan bahwa floatformat floating-point biner sama sekali.

Beberapa kompiler menjamin bahwa floatjenisnya adalah format biner IEEE-754 32 bit. Beberapa tidak. Pada kenyataannya, sebenarnya floatadalah tipe IEEE-754 singlepada sebagian besar platform yang tidak disematkan, meskipun peringatan umum tentang beberapa kompiler yang mengevaluasi ekspresi dalam format yang lebih luas berlaku.

Ada kelompok kerja yang membahas penambahan binding bahasa C untuk revisi 2008 IEEE-754, yang dapat mempertimbangkan untuk merekomendasikan agar typedef tersebut ditambahkan. Jika ini ditambahkan ke C, saya berharap standar C ++ akan mengikuti ... akhirnya.

Stephen Canon
sumber
3
Terlepas dari IEEE-754 atau bukan, itu tetap tidak akan mencegah masalah portabilitas endian.
Tandai B
1
@Pietro: mengubah bahasa tidak akan mempengaruhi kompatibilitas perangkat keras Anda, itu hanya akan menghalangi beberapa perangkat keras dari kepatuhan. Bagaimana jaminan IEEE FP membantu portabilitas?
Potatoswatter
1
@Potatoswatter: Ini akan mendorong vendor perangkat keras untuk memberikan solusi yang sesuai. Jika bagian a mendukung C standar tanpa memerlukan peretasan pustaka pelampung lunak dan bagian b tidak, itu adalah keuntungan pasar untuk bagian a.
Stephen Canon
2
@ Potatoswatter: (Hampir) tidak ada yang peduli dengan kecepatan perangkat keras. Kami peduli dengan kecepatan perangkat lunak yang berjalan di perangkat keras. Perangkat lunak dapat lebih cepat jika perangkat keras yang dijalankan sesuai dengan standar dan perangkat lunak tidak perlu mendeteksi dan menambal 15 kasus khusus yang berbeda tergantung pada platform apa yang dijalankan.
Stephen Canon
8
Bagaimana Anda bisa mendapatkan portabilitas yang lebih baik dengan mencegah kode Anda dikompilasi pada sejumlah arsitektur niche? Entah Anda mengandalkan float sebagai IEEE, dalam hal ini kode Anda sudah akan berjalan pada setiap implementasi yang sesuai dengan IEEE dan tidak ada yang lain, atau tidak, dalam hal ini kode Anda akan berjalan pada sistem yang lebih luas. Jika C ++ dijamin IEEE kepatuhan, kode Anda tidak akan secara ajaib mendapatkan lebih portabel, Anda baru saja mengesampingkan bahwa hal itu bisa pernah dijalankan pada orang-orang arsitektur non-compliant. Logika Anda sepenuhnya mundur.
jalf
30

Jika Anda ingin mengetahui apakah Anda floatadalah tipe IEEE 32-bit, centang std::numeric_limits<float>::is_iec559. Ini adalah konstanta waktu kompilasi, bukan fungsi.

Jika Anda ingin lebih anti peluru, periksa juga std::numeric_limits<float>::digitsuntuk memastikan mereka tidak menggunakan presisi ganda standar IEEE untuk float. Seharusnya 24.

Dalam hal ini long double, lebih penting untuk memeriksa digitskarena ada beberapa format IEEE yang mungkin masuk akal: 128 bit (digit = 113) atau 80 bit (digit = 64).

Tidak praktis untuk memilikinya float32_tkarena Anda biasanya ingin menggunakan perangkat keras floating-point, jika tersedia, dan tidak menggunakan implementasi perangkat lunak.

Potatoswatter
sumber
The long doubleFormat pada OS X (32-bit dan 64-bit Intel) adalah persis IEEE-754 ganda diperpanjang format disimpan dalam rangka little-endian. Tidak ada yang funky sama sekali. Byte 0-7 memegang bidang signifikan, dan byte 8 dan 9 memegang bidang eksponen dan tanda.
Stephen Canon
@ Stephen: itu kabar baik: v). Apakah itu sesuai dengan angka yang saya posting?
Potatoswatter
1
Ingat bahwa diperpanjang ganda (tidak seperti format 754 lainnya) memiliki signifikansi bit di awal yang eksplisit, jadi 5.0Lmemiliki signifikansi a000000000000000. Eksponen tidak biasnya adalah +2, dan bias eksponen ganda diperpanjang adalah 3fff, sehingga eksponen bias untuk 5,0L adalah 4001. Pola byte sebenarnya ketika disimpan dalam urutan little-endian adalah 00 00 00 00 00 00 00 a0 01 40, dan jika Anda melihatnya sebagai dua bilangan bulat 64-bit little-endian, Anda akan melihat dengan tepat apa yang Anda amati.
Stephen Canon
(*) double extended seperti yang diterapkan oleh Intel di perangkat keras. Format diperpanjang ganda sebenarnya tidak disematkan seperti dua format dasar lainnya dari IEEE-754 (1985).
Stephen Canon
@ Stephen: Saya cukup yakin bahwa 4001di little-endian adalah 01 40 00 00 ...Jika tidak ada yang lain, byte yang paling tidak signifikan lebih dulu. Saya berharap urutannya a0 01 40muncul di suatu tempat dalam nomor (jika mereka hanya melakukan rotasi) tetapi saya tidak berpikir Anda telah menjelaskan mengapa a0dan 01 40berada di bagian yang sepenuhnya terpisah.
Potatoswatter
18

Jika Anda merasa memiliki typedef seperti float32_t dan float64_t tidak praktis karena alasan apa pun, Anda pasti terlalu terbiasa dengan OS, kompilator, sehingga Anda tidak dapat terlalu melihat ke luar sarang kecil Anda.

Ada perangkat keras yang secara native menjalankan operasi floating point IEEE 32-bit dan lainnya yang melakukan 64-bit. Terkadang sistem seperti itu bahkan harus saling berkomunikasi, dalam hal ini sangat penting untuk mengetahui apakah double adalah 32 bit atau 64 bit pada setiap platform. Jika platform 32-bit akan melakukan perhitungan yang berlebihan berdasarkan pada nilai 64-bit dari yang lain, kami mungkin ingin memasukkan ke presisi yang lebih rendah tergantung pada waktu dan persyaratan kecepatan.

Saya pribadi merasa tidak nyaman menggunakan pelampung dan ganda kecuali saya tahu persis berapa banyak bit yang ada di platfrom saya. Terlebih lagi jika saya mentransfer ini ke platform lain melalui beberapa saluran komunikasi.

EmbeddedCoder
sumber
"Saya pribadi merasa tidak nyaman menggunakan float dan doubles kecuali saya tahu persis berapa banyak bit yang ada di platfrom saya. Terlebih lagi jika saya mentransfernya ke platform lain melalui beberapa saluran komunikasi." - Maksud Anda, Anda menggunakan format file teks? Dengan ini ada kelemahan dari ukuran file: float 32 membutuhkan 4 byte; ini dalam bentuk teks hanya dapat mewakili empat digit angka ...
Pietro
3

Saat ini ada proposal untuk menambahkan jenis berikut ke dalam bahasa:

decimal32
decimal64
decimal128

yang suatu hari nanti dapat diakses melalui #include <decimal>.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3871.html

Trevor Hickey
sumber
3
Memang, tipe desimal bukanlah tipe floating-point IEEE 754.
Mike DeSimone
TUNGGU! Kita decimal24juga perlu membuat hal-hal seperti membaca file wav dengan sampel 24 bit lebih mudah!
tjwrona1992