I’d suggest you read about LoRaWAN first, and then search this forum. OTAA is unrelated to sending any data, and you cannot expect people to list all options without even telling us what you’ve tried.
Unions work well for sending LoRa packets from C. If you’re using Python / Micropython, struct-packing is the way to go. It keeps the message size small.
Decimals have much higher precision and are usually used within financial applications that require a high degree of accuracy. Decimals are much slower (up to 20X times in some tests) than a double/float. Decimals and Floats/Doubles cannot be compared without a cast whereas Floats and Doubles can. Decimals also allow the encoding or trailing zeros.
Float - 7 digits (32 bit)
Double-15-16 digits (64 bit)
Decimal -28-29 significant digits (128 bit)
The main difference is Floats and Doubles are binary floating point types and a Decimal will store the value as a floating decimal point type. So Decimals have much higher precision and are usually used within monetary (financial) applications that require a high degree of accuracy. But in performance wise Decimals are slower than double and float types.
While true, this applies to programming languages that have a dedicated Decimal type, like .NET in the article you’re linking to. I don’t think many, if any, LoRaWAN nodes will use that. Even if they do, while designing a LoRaWAN application one should consider if that precision makes any sense. 128 bits for a .NET Decimal is a whopping 16 bytes for a single value. In LoRaWAN devices quite often floats are first converted into an integer using some multiplication, to keep a limited number of decimal digits, after which only 2 or 4 bytes are transmitted.