Surely everyone is tired of integers by now! You could multiply everything by 1,000 and have millisecond precision in the simulation... Wouldn't that be easier than floating point? Oh well, floating point. First: It comes in sizes float: 32-bit (single-precision) double: 64-bit (double-precision) long double: 80-bit usually, 128-bit on some architectures __float128: 128-bit (quad-precision) "Q" suffix if defining a constant printf doesn't really support these. quadmath_snprintf will do it Kinda like integers: char: 8-bit short: 16-bit int: 32-bit long: 64-bit (on all but Windows) __int128 128-bit (C23 standardized this, but it was around earlier) Note: x86-64 totally supports 128-bit math And has for a long time You knew that - consider mul and div C/C++ have just been lagging on standardized support Creating a float in hex: Wikipedia single-precision diagram 1 byte for the sign 8 for the exponent 23 for the fraction (or significand) Kinda 24 - there's an implied 1 at the beginning For float, anyway Let's make an assembly program that prints out out movsd to get it into xmm0 Encoding the sign It's a bit The bit is the sign Let's change it and see what happens The exponent: 8-bit integer, but 127 is subtracted from it What's anything raised to the 0th power? Remember, the sign goes first 0x7f8 would set all bits to 1 That's called "inf" Bias: Subtract 127 for actual exponent Let's do some powers of 2 The fraction, or significand: 2 is implied (so we've been leaving it 0) Place value: 1, 0.5, 0.25, 0.125, etc Table on Wikipedia Can we print out a 3? How about something harder, like 7.25? Alright, programming with these: There are a couple ways Olden days: x87 Has a stack of 8 registers Not what we'll use, although our CPU supports it Common these days: SSE That's what gcc seems to use xmm0 etc registers Newer: Advanced Vector Extensions Maybe "newer" isn't ok to say here anymore... Expansion of SSE and xmm registers (see chart) Can we do what we've been doing with ints? Let's make a program that reads a float with scanf We'll need to look at the function calling convention Note here: x86 actually supports multiple returns If you're flexible with convention, can support lots of return values! Then does something with it Then prints out the result Maybe does something else too square root? Epilogue: Performance and floats This one seems ok: https://www.servethehome.com/nvidia-geforce-rtx-3090-review-a-compute-powerhouse/3/ 3D graphics mostly uses single-precision Vector extensions on the CPU: These head toward GPU operations, a little, kinda SIMD, as in "Streaming SIMD Extensions" But the GPU does this way better